springboot+jwt完成登陸認證

本demo用於測試jwt,經過登陸驗證經過後,使用jwt生成token,而後在請求header中攜帶token完成訪問用戶列表信息。java

準備工做:web

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層)spring

2.2 Service方法獲取用戶列表json

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接口app

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工具類:ide

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. 添加攔截器post

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的使用流程。

相關文章
相關標籤/搜索