spring boot + jwt加密

maven

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>4.6.1</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

jwt 工具类

package com.dcy.common.utils;

import cn.hutool.extra.servlet.ServletUtil;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author:dcy
 * @Description:
 * @Date: 2019/11/8 8:40
 */
public class JwtUtil {

    public static final int DAY = 3; // 3 天
    public static final String SECRET = "XX#$%()(#*!()!KL<><MQLMNQNQJQK sdfkjsdrow32234545fdf>?N<:{LWPW";
    public static final String TOKEN_PREFIX = "Bearer";
    public static final String HEADER_STRING = "authorization";

    public static String generateToken(String userJson) {
        HashMap<String, Object> map = new HashMap<>();
        //you can put any data in the map
        map.put("userJson", userJson);
        Calendar now = Calendar.getInstance();
        now.setTime(new Date());
        now.set(Calendar.DATE, now.get(Calendar.DATE) + DAY);
        String jwt = Jwts.builder()
                .setClaims(map)  //
                .setExpiration(now.getTime())//过期时间
                .signWith(SignatureAlgorithm.HS512, SECRET)//SECRET是加密算法对应的密钥,这里使用额是HS256加密算法
                .compact();
        return jwt;
    }

    public static String validateToken(String token) {
        if (token != null) {
            // parse the token.
            Map<String, Object> body = Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
                    .getBody();
            String userJson = (String) (body.get("userJson"));
            if (userJson == null || userJson.isEmpty()) {
                throw new TokenValidationException("Wrong token without username");
            } else {
                return userJson;
            }
        } else {
            throw new TokenValidationException("Missing token");
        }
    }

    /**
     * 获取token
     *
     * @param request
     * @return
     */
    public static String getAuthToken(HttpServletRequest request) {
        Cookie cookie = ServletUtil.getCookie(request, JwtUtil.HEADER_STRING);
        if (cookie != null) {
            return cookie.getValue();
        }
        return null;
    }

    static class TokenValidationException extends RuntimeException {
        public TokenValidationException(String msg) {
            super(msg);
        }
    }
}

加密

JwtUtil.generateToken(JSON.toJSONString(sysUserInfo1))

解密

JwtUtil.validateToken(token);

web环境中怎么使用

登录的时候加密

@PostMapping("/login")
    @ApiOperation(value = "登录")
    @ValidResult
    public ResponseData login(@RequestBody SysUserInfo sysUserInfo) throws Exception {
        // ----------------可以不调用------------------------
        SysUserInfo sysUserInfo1 = iSysUserInfoService.getOne(Wrappers.<SysUserInfo>lambdaQuery().eq(SysUserInfo::getUsername, sysUserInfo.getUsername()));
        if (sysUserInfo1 == null) {
            throw new Exception("用户名和密码错误,请重新输入");
        }
        if ("1".equals(sysUserInfo1.getUserStatus())) {
            throw new Exception("用户已锁定");
        }
        if (!BPwdEncoderUtil.matches(sysUserInfo.getPassword(), sysUserInfo1.getPassword().replace("{bcrypt}", ""))) {
            throw new Exception("用户名和密码错误,请重新输入");
        }
        List<Map<String, Object>> moduleResourcesList = iSysModuleResourcesService.getModuleByUserId(sysUserInfo1.getUserId());
        // 存到redis中
        redisTemplate.opsForValue().set(CommonConstant.REDIS_USER_MODULE_LIST_KEY + sysUserInfo1.getUserId(), moduleResourcesList);
        sysUserInfo1.setPassword(null);
        sysUserInfo1.setPermissionSet(iSysUserInfoService.getPermissionListByUserId(sysUserInfo1.getUserId()));
        sysUserInfo1.setGrantedAuthoritySet(iSysUserInfoService.getAuthRoleSetByUserId(sysUserInfo1.getUserId()));
        return ResponseData.success(200,"请求成功",JwtUtil.generateToken(JSON.toJSONString(sysUserInfo1)));
    }

在定义getUserInfo接口,根据加密信息获取基本信息

@GetMapping("/getUserInfo")
    @ApiOperation(value = "获取用户信息")
    public ResponseData getUserInfo(HttpServletRequest request) throws Exception {
        String authorization = JwtUtil.getAuthToken(request);
        String userJson = JwtUtil.validateToken(authorization);
        SysUserInfo sysUserInfo = JSON.parseObject(userJson, SysUserInfo.class);
        sysUserInfo.setPassword(null);
        return ResponseData.success(sysUserInfo);
    }

定义拦截器

package com.dcy.filter;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.dcy.common.constant.CommonConstant;
import com.dcy.common.model.ResponseData;
import com.dcy.common.utils.JwtUtil;
import com.dcy.modules.user.model.SysUserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;

/**
 * @Author:dcy
 * @Description:
 * @Date: 2019/11/8 8:51
 */
public class UserAuthRestInterceptor extends HandlerInterceptorAdapter {

    private final AntPathMatcher antPathMatcher = new AntPathMatcher();

    private static final String ADMIN_USER_TYPE = "0";

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //取header 的内容
        String token = JwtUtil.getAuthToken(request);
        if (StrUtil.isNotBlank(token)) {
            //验证token
            String userJson = JwtUtil.validateToken(token);
            // 转换对象
            SysUserInfo sysUserIno = JSON.parseObject(userJson, SysUserInfo.class);
            if (sysUserInfo != null){
                return true;
            }
        } else {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter out = response.getWriter();
            out.append(JSON.toJSONString(ResponseData.error(3000,"没有token")));
            return false;
        }
        return super.preHandle(request, response, handler);
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
    }

    /**
     * 获取请求中的url
     *
     * @param url
     * @return
     */
    private String getUrl(String url) {
        //获取当前访问url
        int firstQuestionMarkIndex = url.indexOf("?");
        if (firstQuestionMarkIndex != -1) {
            return url.substring(0, firstQuestionMarkIndex);
        }
        return url;
    }

}

定义不拦截url

在application.yml中定义ignored变量

ignored: |
  /login,/v2/*,/webjars/**,/**/favicon.ico,/swagger-resources/**,/druid/**,/dict/getDictListByType,/dict/getDictTreeListByGroupType,/swagger-ui.html,/file/**,/user/getUserInfoByUsername,/user/registerUser,
  /depa/getHosList,/depa/getSubListByHosId

| 是换行使用

注入拦截器

/**
 * @Author:dcy
 * @Description:
 * @Date: 2019/11/8 8:47
 */
@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Value("${ignored}")
    private List<String> ignored;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // token拦截器 获取用户信息
        registry.addInterceptor(userAuthRestInterceptor()).addPathPatterns("/**").excludePathPatterns(ignored);
    }

    @Bean
    public UserAuthRestInterceptor userAuthRestInterceptor(){
        return new UserAuthRestInterceptor();
    }
}

思路和代码都已经提供,其他的靠大家了。

拦截器写的比较简单,因为我写的业务不太符合大家的,所有我的代码没粘出来,自己可以进行自己的业务处理,比如URL判断某个角色是否能访问等等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值