Java后台使用token驗證用戶是否登錄


與cookie相比較的優勢:

1、支持跨域訪問,將token置於請求頭中,而cookie是不支持跨域訪問的;

2、無狀態化,服務端無需存儲token,只需要驗證token信息是否正確即可,而session需要在服務端存儲,一般是通過cookie中的sessionID在服務端查找對應的session;

3、無需綁定到一個特殊的身份驗證方案(傳統的用戶名密碼登陸),只需要生成的token是符合我們預期設定的即可;

4、更適用於移動端(Android,iOS,小程序等等),像這種原生平台不支持cookie,比如說微信小程序,每一次請求都是一次會話,當然我們可以每次去手動為他添加cookie,詳情請查看博主另一篇博客;

5、避免CSRF跨站偽造攻擊,還是因為不依賴cookie;

6、非常適用於RESTful API,這樣可以輕易與各種后端(java,.net,python......)相結合,去耦合

基於jwt的token認證實現:

1、加入jwt的依賴

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.3.0</version>
</dependency>

2、聲明2個變量過期時間和token秘鑰(UUID可能會更好,我是自己隨便輸的),token秘鑰用於后面解密

//設置30分鍾過期
    private static final long EXPIRE_DATE=30*60*1000;
    //token秘鑰
    private static final String TOKEN_SECRET = "EQIUBFKSJBFJH2367816BQWE";

3、加密

public static String tokenTest (String username,String password){        
 
        String token = "";
        try {
            //過期時間
            Date date = new Date(System.currentTimeMillis()+EXPIRE_DATE);
            //秘鑰及加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            //設置頭部信息
            Map<String,Object> header = new HashMap<>();
            header.put("typ","JWT");
            header.put("alg","HS256");
            //攜帶username,password信息,生成簽名
            token = JWT.create()
                    .withHeader(header)
                    .withClaim("username",username)
                    .withClaim("password",password).withExpiresAt(date)
                    .sign(algorithm);
        }catch (Exception e){
            e.printStackTrace();
            return  null;
        }
        return token;
}

4、解密。該方法的參數token是加密方法的返回值

    public static boolean verify(String token){
        /**
         * @desc   驗證token,通過返回true
         * @create 2019/1/18/018 9:39
         * @params [token]需要校驗的串
        **/
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return  false;
        }
    }

5、登錄接口

   @RequestMapping(value = "/logon")
    public JsonRESTResult getUserInfo(HttpSession session ,String userName, String password) {
        /**
        * @author zdj
        * @create 2019/1/17/017 9:55
        * @params [session, userName, password]
        **/
        JsonRESTResult jsonRESTResult = new JsonRESTResult();        
        //使用token工具類生成token串
        String token  = TokenUtil.tokenTest(userName,password);
        //根據用戶名密碼查找用戶
        User user = loginService.findUser(userName,password);
        if (user !=null){
            //將用戶對象放到session中
            session.setAttribute("USER_INFO",user);
            //用戶無操作30分鍾需重新登錄
            session.setMaxInactiveInterval(60*30);
            Map map = new HashMap<>();
            map.put("USERINFO",user);
            map.put("SESSIONID",session.getId());
            map.put("token",token);
            jsonRESTResult.setCode(JsonRESTResultMsg.CODE_800.getCode());
            jsonRESTResult.setMsg("登錄成功");
            jsonRESTResult.setData(map);
            return jsonRESTResult;
        }else{
            jsonRESTResult.setCode(JsonRESTResultMsg.CODE_500.getCode());
            jsonRESTResult.setMsg("登錄失敗,用戶名密碼錯誤");
            jsonRESTResult.setData(null);
            return jsonRESTResult;
        }
 
    }

6、判斷用戶是否登錄接口

@RequestMapping("/judgeLogin")
    public JsonRESTResult judgeLogin(String token,HttpSession session){
        JsonRESTResult jsonRESTResult = new JsonRESTResult();
        if (TokenUtil.verify(token)){
            User user = (User)session.getAttribute("USER_INFO");
            jsonRESTResult.setCode(JsonRESTResultMsg.CODE_800.getCode());
            jsonRESTResult.setData(user);
            jsonRESTResult.setMsg("用戶登錄成功");
        }else {
            jsonRESTResult.setCode(JsonRESTResultMsg.CODE_500.getCode());
            jsonRESTResult.setMsg("未登錄或已過期");
        }
        return jsonRESTResult;
    }

完整工具類

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
 
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
 * @desc   使用token驗證用戶是否登錄
 * @author zdj
 * @create 2019/1/18/018 9:41
**/
public class TokenUtil {
    //設置30分鍾過期
    private static final long EXPIRE_DATE=30*60*1000;
    //token秘鑰
    private static final String TOKEN_SECRET = "EQIUBFKSJBFJH2367816BQWE";
 
//    private static String username = "zdj" ;
//    private static String password = "123" ;
 
    public static String tokenTest (String username,String password){
 
        String token = "";
        try {
            //過期時間
            Date date = new Date(System.currentTimeMillis()+EXPIRE_DATE);
            //秘鑰及加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            //設置頭部信息
            Map<String,Object> header = new HashMap<>();
            header.put("typ","JWT");
            header.put("alg","HS256");
            //攜帶username,password信息,生成簽名
            token = JWT.create()
                    .withHeader(header)
                    .withClaim("username",username)
                    .withClaim("password",password).withExpiresAt(date)
                    .sign(algorithm);
        }catch (Exception e){
            e.printStackTrace();
            return  null;
        }
        return token;
    }
 
    public static boolean verify(String token){
        /**
         * @desc   驗證token,通過返回true
         * @create 2019/1/18/018 9:39
         * @params [token]需要校驗的串
        **/
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return  false;
        }
    }
 
    public static void main(String[] args) {
        /**
         * @desc   token工具類測試
         * @create 2019/1/18/018 9:40
         * @params [args]
        **/
//        System.out.println(tokenTest(username,password));
//        System.out.println(verify(tokenTest(username,password)));
    }
}

————————————————
版權聲明:本文為博主「殘月灬清風」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zdj18166896501/article/details/86534596


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM