SSM框架中实现登录认证与鉴权

基本思路:
客户端发起登录请求到后端服务器,验证用户名和密码后,生成jwt令牌返回给客户端,把一些不敏感的信息存入到jwt的载荷中,由客户端自行存储这个令牌,以后的每次请求都要携带这个jwt令牌,我们称为token,再创建一个拦截器拦截除了登录外的所有请求,在这个拦截器中我们要验证token的合法性,然后解析出载荷信息,放入到当前线程当中,方便在后面的业务中会用。
注意:
默认采用手机号码后6位作为密码,使用md5加密后的密码。
代码如下:
登录部分:

    @Override
    public String login(LoginDto loginDto) {
        //判空
        if(loginDto == null){
            throw new CustomerException(ResultEnum.USERNAME_OR_PASSWORD_ERROR);
        }
        //查询用户信息
        LambdaQueryWrapper<Admin> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Admin::getUsername,loginDto.getUsername());
        Admin admin = getBaseMapper().selectOne(queryWrapper);
        if(admin == null){
            throw new CustomerException(ResultEnum.USER_NOT_EXIT);
        }
        //将获取到的盐和用户输入的密码进行md5加密并与数据库中的密码进行对比
        String salt = admin.getSalt();
        String md5Password = DigestUtil.md5Hex(loginDto.getPassword() + salt);
        if(!md5Password.equals(admin.getPassword())){
            throw new CustomerException(ResultEnum.USERNAME_OR_PASSWORD_ERROR);
        }
        //生成jwt类型的token返回给客户端
        HashMap<String, Object> payload = new HashMap<>();
        payload.put("id",admin.getId());
        payload.put("name",admin.getName());
        payload.put("username",admin.getUsername());
        payload.put("image",admin.getImage());
        payload.put("phone",admin.getPhone());
        payload.put("expire",System.currentTimeMillis() + 1000 * 60 * 60 *2);
        String token = TokenUtils.createToken(payload);
        return token;
    }

编写拦截器:

public class AuthInterceptor implements HandlerInterceptor {
    /**
     * 处理器执行之前
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        //获取token
        String token = httpServletRequest.getHeader("token");
        if(StringUtils.isEmpty(token)){
            token = httpServletRequest.getParameter("token");
            if(StringUtils.isEmpty(token)){
                Result rs = Result.buildFail(ResultEnum.TOKEN_NOT_EMPTY);
                ResponseUtils.responseToJson(httpServletResponse, JsonUtils.objectToJson(rs));
                return false;
            }
        }
        //校验jwt的合法性
        if(!JWTUtil.verify(token, TokenUtils.KEY.getBytes())){
            Result rs = Result.buildFail(ResultEnum.TOKEN_ERROR);
            ResponseUtils.responseToJson(httpServletResponse, JsonUtils.objectToJson(rs));
            return false;
        }

        JWT jwt = JWTUtil.parseToken(token);
        NumberWithFormat expire = (NumberWithFormat) jwt.getPayload("expire");
        if(System.currentTimeMillis() > expire.longValue()){
            Result rs = Result.buildFail(ResultEnum.TOKEN_EXPIRE);
            ResponseUtils.responseToJson(httpServletResponse, JsonUtils.objectToJson(rs));
            return false;
        }
        HashMap<String, Object> payload = new HashMap<>();
        payload.put("id",jwt.getPayload("id"));
        payload.put("name",jwt.getPayload("name"));
        payload.put("username",jwt.getPayload("username"));
        payload.put("image",jwt.getPayload("image"));
        payload.put("phone",jwt.getPayload("phone"));
        AdminThreadLocal.set(payload);
        return true;  //true放行,false拦截
    }
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        AdminThreadLocal.remove();
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

配置拦截器:

    <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path="/admin/login"/>
            <bean class="com.gxa.op.permisson.AuthInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

使用到的工具类:

public class AdminThreadLocal {

    private static ThreadLocal<Map<String,Object>> tl = new ThreadLocal<>();

    /**
     * 绑定当前线程
     */
    public static void set(Map<String,Object> map){
        tl.set(map);
    }
    /**
     * 获取当前线程
     */
    public static Map<String,Object> get(){
        return tl.get();
    }

    /**
     * 移除当前线程绑定的用户信息
     */
    public static void remove(){
        tl.remove();
    }
}
public class TokenUtils {
    public static final String KEY = "dnjsdfhjdvhdjvnbjxcbjhcbvsdhjajdejihsfnj";
    public static String createToken(Map<String,Object> payload){
        return JWTUtil.createToken(payload,KEY.getBytes());
    }
}
<dependency>
	<groupId>cn.hutool</groupId>
	<artifactId>hutool-all</artifactId>
	<version>xxx</version>
 </dependency>

此文章仅作为学习记录

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值