# 当前登录用户

# 认证凭据解析

   在 Heimdall 框架中,用户认证凭据通过 SimpleSession 进行管理。SimpleSession是 Http Session 的一个实现,包括了,首次访问时间,最后访问时间,是否过期,对端主机地址等基本信息。

  用户认证通过,则生成对应的 Session,并且将 Session 信息缓存,通知将 Session 返回给上层应用,如果开启了 Cookie 功能,Session 创建后,还会同步往前端浏览器发出 Set-Cookie 指令,写入 Cookie。

  客户端访问后台服务,携带认证凭据(SessionId token 等),Heimdall 框架解析认证凭据,并从缓存中查找,如果找到,则返回当前登录用户信息,否则抛出未认证异常。

  Heimdall 支持从 Cookie、Header、Query 中获取认证凭据。对于某些非浏览器应用场景(如:app、小程序等),不支持 Cookie,则可以禁用 Cookie,只使用 Session。此时 SessionID也就相当于是俗称的:”token“,你懂的,咪和猫的区别。。。。

获取认证凭据的方法如下:

/**
     * 解析请求中的SessionId
     * <p>
     * <p>
     * 1、如果Cookie开启,首先从Cookie解析,有,则返回
     * <p>
     * 2、如果没有,从Header中解析,有则返回
     * <p>
     * 3、header中没有,从request parameters参数中解析,返回
     *
     * @param request the request
     * @return the string
     */
    public String resolveSessionId(HttpServletRequest request) {
        final String sessionName = ConfigManager.getConfig().getSession().getSessionName();
        if (ConfigManager.getConfig().getCookie().getEnabled()) {
            final Cookie cookie = sessionDAO.getCookieService().getCookie();
            if (null != cookie) {
                log.debug("解析请求 SessionId | Cookie 中携带了SessionId: [{} = {}]", sessionName, cookie.getValue());
                return cookie.getValue();
            }
        }
        String token = request.getHeader(sessionName);
        if (StrUtils.isBlank(token)) {
            String sessionId = request.getParameter(sessionName);
            log.debug("解析请求 SessionId | Parameters 中携带了SessionId: [{} = {}]", sessionName, sessionId);
            return sessionId;
        }
        log.debug("解析请求 SessionId | Headers 中携带了SessionId: [{} = {}]", sessionName, token);
        return token;
    }

# 获取当前登录用户

Heimdall 框架提供了如下几种获取当前登录用户信息的方式:

  • 认证管理器获取
  • 注解获取

# 认证管理器获取

使用方法:

authenticationManager.getCurrentUser(Boolean throwEx)

示例如下:

	/**
     *  认证管理器
     */
    @Autowired
    private AuthenticationManager authenticationManager;


	//获取当前登录用户信息
    @Override
    public SysUserDTO getCurrentUser(boolean fromDb, boolean throwEx) {
        final SimpleSession currentUser = authenticationManager.getCurrentUser(throwEx);
        if (null != currentUser && null != currentUser.getDetails()) {
            AppUserDetails userDetails = (AppUserDetails) currentUser.getDetails();
            if (fromDb) {
                final Long id = userDetails.getUser().getId();
                final SysUserEntity entityById = getEntityById(SysUserEntity.class, id);
                return userMapper.toDto(entityById);
            }
            return userDetails.getUser();
        }
        return null;

    }

# 注解获取

针对 Spring 框架 Heimdall 提供了当前用户注解实现,可通过定义addArgumentResolvers实现,参考以下代码:

public class AbstractWebMvcConfigurer implements WebMvcConfigurer {
	.......

    /**
     * 当前登录用户参数解析器
     */
    @Autowired
    private CurrentUserRequestArgumentResolver currentUserRequestArgumentResolver;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        log.warn("初始化 当前用户参数注解解析器");
        argumentResolvers.add(currentUserRequestArgumentResolver);
    }
	.......
}

同时,框架也提供了 Mvc 配置基础类:com.luter.heimdall.boot.starter.config.AbstractWebMvcConfigurer, 如果没有特殊需求,可直接扩展使用即可,如下:

@Configuration
@Slf4j
public class MvcConfig extends AbstractWebMvcConfigurer {

}

# 注解使用

	@GetMapping("/user")
    public SimpleSession getCurrentUser(@CurrentUser SimpleSession user) {
        return user;
    }

注意:此注解是通过authenticationManager.getCurrentUser()来获取的当前登录用户信息,所以需要对返回结果进行空值判断。当用户未登录或者已经过期的情况下,会主动抛出 401 异常。

上次更新:: 1/25/2021, 4:26:40 PM