如何确保用户真实登陆?超时重新登陆?JWT来了。

什么是JWT

JWT(Json Web Token),是一种工具,格式为XXXX.XXXX.XXXX的字符串,JWT以一种安全的方式在用户和服务器之间传递存放在JWT中的不敏感信息。

为什么要用JWT

设想这样一个场景,在我们登录一个网站之后,再把网页或者浏览器关闭,下一次打开网页的时候可能显示的还是登录的状态,不需要再次进行登录操作,通过JWT就可以实现这样一个用户认证的功能。当然使用Session可以实现这个功能,但是使用Session的同时也会增加服务器的存储压力,而JWT是将存储的压力分布到各个客户端机器上,从而减轻服务器的压力。

JWT操作流程图

Spring Boot整合

1. pom.xml配置依赖

<dependency>    <groupId>io.jsonwebtoken</groupId>    <artifactId>jjwt</artifactId>    <version>0.9.0</version></dependency>

2. 添加过滤器

这个类声明了一个JWT过滤器类,从Http请求中提取JWT的信息,并使用了secretkey这个密匙对JWT进行验证。

/** * 拦截器验证类 * @author zhouzhaodong */public class JwtFilter extends GenericFilterBean {    /**     * 秘钥     */    public static final String SECRET_KEY = "secretkey";    @Override    public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)            throws IOException, ServletException {        final HttpServletRequest request = (HttpServletRequest) req;        final HttpServletResponse response = (HttpServletResponse) res;        // 从request中获取authorization        final String authHeader = request.getHeader("authorization");        // 如果Http请求是OPTIONS,那么只需返回状态代码200即可。        String options = "OPTIONS";        if (options.equals(request.getMethod())) {            response.setStatus(HttpServletResponse.SC_OK);        }        else {            // 判断token是否是用Bearer 开头的            String header = "Bearer ";            if (authHeader == null || !authHeader.startsWith(header)) {                throw new ServletException("Missing or invalid Authorization header");            }            // 然后从授权处获取JWT令牌            final String token = authHeader.substring(7);            try {                // 使用JWT解析器检查签名是否与Key "secretkey "有效。                final Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();                // 在请求标题中添加claims                request.setAttribute("claims", claims);            } catch (final SignatureException e) {                throw new ServletException("Invalid token");            }        }        chain.doFilter(req, res);    }}

3. 拦截器

/** * 拦截器 * @author zhouzhaodong */@Configurationpublic class JwtCfg {    @Bean    public FilterRegistrationBean<JwtFilter> jwtFilter() {        final FilterRegistrationBean<JwtFilter> registrationBean = new FilterRegistrationBean<>();        registrationBean.setFilter(new JwtFilter());        // 对/test/*下的url进行拦截验证        registrationBean.addUrlPatterns("/test/*");        return registrationBean;    }}

4. 写一个JWT生成的方法类

/** * JWT生成类 * @author zhouzhaodong */public class JwtUtils {    public static final String SUBJECT = "admin";    /**     * 过期时间,毫秒,一天     */    public static final long EXPIRE = 1000 * 60 * 60 * 24;    /**     * 秘钥     */    public static final String SECRET_KEY = "secretkey";    /**     * 生成jwt     * @param userName     * @param passWord     * @return     */    public static String geneJsonWebToken(String userName, String passWord) {        if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(passWord)) {            return "用户名或密码不能为空";        }        return Jwts.builder().setSubject(SUBJECT)                .claim("userName", userName)                .setIssuedAt(new Date())                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))                .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();    }}

5. 写测试方法

/** * 登陆 * @author zhouzhaodong */@RestControllerpublic class TestController {    @RequestMapping("/login")    public String login(HttpServletResponse response, String userName, String passWord) {        // 假装判断一下登陆是否成功        if(userName == null || "".equals(userName) || passWord == null || "".equals(passWord)){            return "用户名或者密码不能为空";        }        String token = JwtUtils.geneJsonWebToken(userName, passWord);        // 将token放在响应头        response.setHeader("Authorization", token);        return token;    }    @RequestMapping("/secure/check")    public String check(){        return "登陆成功";    }}

6. 启动验证

1. 运行IDEA

2. 使用postman进行测试

首先需要访问login获取token:

然后拿着该token去登录:

完成了,是不是比较简单!

源码地址

https://github.com/zhouzhaodo...

个人网站链接

http://www.zhouzhaodong.xyz