zoukankan      html  css  js  c++  java
  • springboot+jwt完成登录认证

    本demo用于测试jwt,通过登录验证通过后,使用jwt生成token,然后在请求header中携带token完成访问用户列表信息。

    准备工作:

    1. 实体类SysUser.java

    package com.king.entity;
    
    import lombok.Data;
    
    @Data
    public class SysUser {
    
        private String id;
        private String username;
        private String password;
    
        public SysUser(String username,String password){
            this.username = username;
            this.password = password;
        }
    }
    View Code

    2. 1 Service方法验证用户账号和密码(这里偷懒没写dao层)

    2.2 Service方法获取用户列表

    package com.king.service;
    
    import com.king.entity.SysUser;
    import org.springframework.stereotype.Service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @Service
    public class SysUserServiceImpl implements SysUserService{
    
        @Override
        public boolean login(SysUser user) {
            String username = user.getUsername();
            String password = user.getPassword();
            if(username.equals("king") && password.equals("123")){
                return true;
            }
            return false;
        }
    
        @Override
        public List<SysUser> getList() {
    
            SysUser user1= new SysUser("king1","12345");
            SysUser user2 = new SysUser("king2","12345");
            SysUser user3 = new SysUser("king3","12345");
            List<SysUser> list = new ArrayList<>();
            list.add(user1);
            list.add(user2);
            list.add(user3);
            return list;
        }
    }
    View Code

    2.3 Service接口

    package com.king.service;
    
    import com.king.entity.SysUser;
    
    import java.util.List;
    
    public interface SysUserService {
    
        public boolean login(SysUser user);
    
        public List<SysUser> getList();
    }
    View Code

    重点来了,接下来实现token工具类:

    3. 使用jwt完成签名生成方法与验证方法

    package com.king.util;
    
    import com.auth0.jwt.JWT;
    import com.auth0.jwt.JWTVerifier;
    import com.auth0.jwt.algorithms.Algorithm;
    import com.auth0.jwt.interfaces.DecodedJWT;
    import com.king.entity.SysUser;
    
    import java.util.Date;
    
    public class TokenUtil {
    
        private static final long EXPIRE_TIME= 15*60*1000;
        private static final String TOKEN_SECRET="token123";  //密钥盐
    
    
        /**
         * 签名生成
         * @param user
         * @return
         */
        public static String sign(SysUser user){
    
            String token = null;
            try {
                Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
                token = JWT.create()
                        .withIssuer("auth0")
                        .withClaim("username", user.getUsername())
                        .withExpiresAt(expiresAt)
                        // 使用了HMAC256加密算法。
                        .sign(Algorithm.HMAC256(TOKEN_SECRET));
            } catch (Exception e){
                e.printStackTrace();
            }
            return token;
    
        }
    
    
        /**
         * 签名验证
         * @param token
         * @return
         */
        public static boolean verify(String token){
    
    
            try {
                JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
                DecodedJWT jwt = verifier.verify(token);
                System.out.println("认证通过:");
                System.out.println("issuer: " + jwt.getIssuer());
                System.out.println("username: " + jwt.getClaim("username").asString());
                System.out.println("过期时间:      " + jwt.getExpiresAt());
                return true;
            } catch (Exception e){
                return false;
            }
    
        }
    
    
    
    }

    4. 添加拦截器

    package com.king.interceptor;
    
    import com.alibaba.fastjson.JSONObject;
    import com.king.util.TokenUtil;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.PrintWriter;
    
    @Component
    public class TokenInterceptor implements HandlerInterceptor {
    
    
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception{
    
            if(request.getMethod().equals("OPTIONS")){
                response.setStatus(HttpServletResponse.SC_OK);
                return true;
            }
    
            response.setCharacterEncoding("utf-8");
    
            String token = request.getHeader("admin-token");
            if(token != null){
                boolean result = TokenUtil.verify(token);
                if(result){
                    System.out.println("通过拦截器");
                    return true;
                }
            }
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter out = null;
            try{
                JSONObject json = new JSONObject();
                json.put("success","false");
                json.put("msg","认证失败,未通过拦截器");
                json.put("code","50000");
                response.getWriter().append(json.toJSONString());
                System.out.println("认证失败,未通过拦截器");
                //        response.getWriter().write("50000");
            }catch (Exception e){
                e.printStackTrace();
                response.sendError(500);
                return false;
            }
    
    
            return false;
    
        }
    
    
    
    
    
    }
    View Code

    5. 配置拦截器

    package com.king.config;
    
    import com.king.interceptor.TokenInterceptor;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 拦截器配置
     */
    @Configuration
    public class IntercepterConfig implements WebMvcConfigurer {
    
        private TokenInterceptor tokenInterceptor;
    
        //构造方法
        public IntercepterConfig(TokenInterceptor tokenInterceptor){
            this.tokenInterceptor = tokenInterceptor;
        }
    
        @Override
        public void addInterceptors(InterceptorRegistry registry){
            List<String> excludePath = new ArrayList<>();
            excludePath.add("/user_register"); //注册
            excludePath.add("/login"); //登录
            excludePath.add("/logout"); //登出
            excludePath.add("/static/**");  //静态资源
            excludePath.add("/assets/**");  //静态资源
    
            registry.addInterceptor(tokenInterceptor)
                    .addPathPatterns("/**")
                    .excludePathPatterns(excludePath);
            WebMvcConfigurer.super.addInterceptors(registry);
    
        }
    
    }
    View Code

    6. controller层实现登录方法和获取用户列表方法

    package com.king.controller;
    
    
    import com.king.entity.SysUser;
    import com.king.service.SysUserService;
    import com.king.util.TokenUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @RestController
    public class UserController {
    
    
        @Autowired
        private SysUserService userService;
    
    
        @PostMapping(value="/login")
        @ResponseBody
        public Map<String,Object> login(String username,String password){
    
            Map<String,Object> map = new HashMap<>();
            SysUser user = new SysUser(username,password);
    
            if(userService.login(user)){
                String token = TokenUtil.sign(user);
                if(token != null){
                    map.put("code", "10000");
                    map.put("message", "认证成功");
                    map.put("token", token);
                    return map;
                }
            }
    
            map.put("code", "0000");
            map.put("message", "认证失败");
            return map;
    
        }
    
        @PostMapping(value="/getList")
        public List<SysUser> getList(){
    
            List userList = userService.getList();
            return userList;
    
        }
    
    
    
    }
    View Code

    接下来测试:

    1. 使用postman提交登录信息,当密码故意输错时,返回验证失败。

    2. 提交正确的用户名和密码,验证通过,可以获取到token信息。

    3. 使用token信息放到header中,key设置为admin-token,然后请求用户列表信息。

    在后台我们可以看到token携带到用户信息和token的有效时间:

    以上为整个jwt的使用流程。

  • 相关阅读:
    《我想进大厂》之mysql夺命连环13问
    抽象数据类型的表示与实现
    数据结构两个层次——逻辑结构和存储结构
    单链表的两种构造函数
    使用malloc函数或new运算符为链表结点分配内存空间
    基于Vue全家桶开发的前端组件管理平台
    JS菱形镂空
    JS使用for循环实现九九乘法表数字颜色不同
    JS——个人所得税
    JAVA常见关键字
  • 原文地址:https://www.cnblogs.com/30go/p/10963924.html
Copyright © 2011-2022 走看看