Jwt在javaweb項目中的應用核心步驟解讀

1.引入jwt依賴

       <!--引入JWT依賴,因爲是基於Java,因此須要的是java-jwt-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
2.建立兩個註解,PassToken和UserLoginToken,用於在項目開發中,若是須要權限校驗就標註userlogintoken,若是訪問的資源不須要權限驗證則正常編寫不須要任何註解,若是用的的請求時登陸操做,在用戶登陸的方法上增長passtoken註解。
 
passtoken
package com.pjb.springbootjjwt.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author jinbin
 * @date 2018-07-08 20:38
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
    boolean required() default true;
}
userlogintoken
package com.pjb.springbootjjwt.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author jinbin
 * @date 2018-07-08 20:40
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
    boolean required() default true;
}
註解解析:從上面咱們新建的兩個類上咱們能夠看到主要的等學習到的就四點
第一:如何建立一個註解
第二:在咱們自定義註解上新增@Target註解(註解解釋:這個註解標註咱們定義的註解是能夠做用在類上仍是方法上仍是屬性上面)
第三:在咱們自定義註解上新增@Retention註解(註解解釋:做用是定義被它所註解的註解保留多久,一共有三種策略,SOURCE 被編譯器忽略,CLASS  註解將會被保留在Class文件中,但在運行時並不會被VM保留。這是默認行爲,全部沒有用Retention註解的註解,都會採用這種策略。RUNTIME  保留至運行時。因此咱們能夠經過反射去獲取註解信息。
第四:boolean required() default true;  默認required() 屬性爲true
3.服務端生成Token

4.服務端攔截請求驗證Token的流程

 

第一步:建立攔截器,方法執行以前執行攔截

第二步:判斷是否請求方法

第三步:判斷方法是不是登陸方法

第三步:判斷是否爲須要權限驗證的方法

5.在項目中的應用

附上攔截器源代碼java

package com.pjb.springbootjjwt.interceptor;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.pjb.springbootjjwt.annotation.PassToken;
import com.pjb.springbootjjwt.annotation.UserLoginToken;
import com.pjb.springbootjjwt.entity.User;
import com.pjb.springbootjjwt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;


/**
 * @author jinbin
 * @date 2018-07-08 20:41
 */
public class AuthenticationInterceptor implements HandlerInterceptor {

    @Autowired
    UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {

        // 從 http 請求頭中取出 token
        String token = httpServletRequest.getHeader("token");
        // 若是不是映射到方法直接經過
        if (!(object instanceof HandlerMethod)) {
            return true;
        }


        HandlerMethod handlerMethod = (HandlerMethod) object;
        Method method = handlerMethod.getMethod();
        //檢查是否有passtoken註釋,有則跳過認證
        if (method.isAnnotationPresent(PassToken.class)) {
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) {
                return true;
            }
        }


        //檢查有沒有須要用戶權限的註解
        if (method.isAnnotationPresent(UserLoginToken.class)) {
            UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
            if (userLoginToken.required()) {
                // 執行認證
                if (token == null) {
                    throw new RuntimeException("無token,請從新登陸");
                }
                // 獲取 token 中的 user id
                String userId;
                try {
                    userId = JWT.decode(token).getAudience().get(0);
                } catch (JWTDecodeException j) {
                    throw new RuntimeException("401");
                }
                User user = userService.findUserById(userId);
                if (user == null) {
                    throw new RuntimeException("用戶不存在,請從新登陸");
                }

                // 驗證 token
                JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();

                try {
                    jwtVerifier.verify(token);
                } catch (JWTVerificationException e) {
                    throw new RuntimeException("401");
                }
                return true;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

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

    }


}
View Code
相關文章
相關標籤/搜索