token 值处理及鉴权源代码介绍
登录功能代码主要用于验证登录信息并生成 token
值,当然这只是第一步——生成身份验证信息,接下来笔者介绍登录模块中的用户身份保持和身份验证。用户身份保持和身份验证这两个概念并不复杂,结合前文中的登录流程理解即可。前文中处理的流程分支是 token
值不存在,进入登录页面。那么,如果 token
值存在,即已经登录成功,又该怎样进行身份验证?登录成功后会获得一个 token
值,该怎样使用这个 token
值?本节就来讲解这些知识。
后端处理 token
值的步骤总结如下。
-
生成
token
值,这在 3.2 节已经介绍过。 -
获取请求中的
token
值。 -
验证
token
值,查看是否存在、是否过期等。
实现登录功能后,需要对用户的登录状态进行验证,这里所说的登录状态即 “token
值是否存在及 token
值是否有效”,而 token
值是否有效,则通过后端代码验证。由于大部分接口都需要进行登录验证,如果每个方法都添加查询用户数据的语句,则有些多余,因此对方法做了抽取,通过注解切面的形式返回用户信息。
对于管理员用户的身份鉴权,在功能实现时定义了一个 @TokenToAdminUser
注解。之后自定义了一个方法参数解析器,在需要用户身份信息的方法定义上添加 @TokenToAdminUser
注解,通过方法参数解析器来获得当前登录的对象信息,自定义的 TokenToAdminUserMethodArgumentResolver
代码如下:
package ltd.user.cloud.newbee.config.handler;
import ltd.user.cloud.newbee.annotation.TokenToAdminUser;
import ltd.user.cloud.newbee.dao.NewBeeAdminUserTokenMapper;
import ltd.user.cloud.newbee.entity.AdminUserToken;
import ltd.common.cloud.newbee.exception.NewBeeMallException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
@Component
public class TokenToAdminUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private NewBeeAdminUserTokenMapper newBeeAdminUserTokenMapper;
public TokenToAdminUserMethodArgumentResolver() {
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
if (parameter.hasParameterAnnotation(TokenToAdminUser.class)) {
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) {
if (parameter.getParameterAnnotation(TokenToAdminUser.class) instanceof TokenToAdminUser) {
String token = webRequest.getHeader("token");
if (null != token && !"".equals(token) && token.length() == 32) {
AdminUserToken adminUserToken = newBeeAdminUserTokenMapper.selectByToken(token);
if (adminUserToken == null) {
NewBeeMallException.fail("ADMIN_NOT_LOGIN_ERROR");
} else if (adminUserToken.getExpireTime().getTime() <= System.currentTimeMillis()) {
NewBeeMallException.fail("ADMIN_TOKEN_EXPIRE_ERROR");
}
return adminUserToken;
} else {
NewBeeMallException.fail("ADMIN_NOT_LOGIN_ERROR");
}
}
return null;
}
}
源代码在 newbee-mall-cloud-user-web
模块下的 ltd.user.cloud.newbee.service.config.handler.TokenToAdminUserMethodArgumentResolver
类中。
执行逻辑如下。
-
获取请求头中的
token
值,若不存在,则返回错误信息给前端;若存在,则继续后续流程。 -
通过
token
值来查询AdminUserToken
对象,查看是否存在或是否过期,若不存在或已过期,则返回错误信息给前端;若正常,则继续后续流程。 -
在
WebMvcConfigurer
中配置TokenToAdminUserMethodArgumentResolver
,使其生效,代码如下:
@Configuration
public class AdminUserWebMvcConfigurer extends WebMvcConfigurationSupport {
@Autowired
private TokenToAdminUserMethodArgumentResolver tokenToAdminUserMethodArgumentResolver;
/**
* @param argumentResolvers
* @tip @TokenToAdminUser 注解处理方法
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(tokenToAdminUserMethodArgumentResolver);
}
}
源代码在 newbee-mall-cloud-user-web
模块下的 ltd.user.cloud.newbee.config.AdminUserWebMvcConfigurer
类中。
如此,在需要进行用户鉴权的 API
定义上添加 @TokenToAdminUser
注解,之后进行相应的代码逻辑处理。在本实战项目中,有两种用户身份,分别是 管理员用户 和 商城用户,两种身份的登录功能及鉴权功能的实现方式基本一致,后续就不再占用篇幅单独介绍商城用户的登录功能和鉴权功能了。