国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Springboot+redis實現(xiàn)token的登錄認證

這篇具有很好參考價值的文章主要介紹了Springboot+redis實現(xiàn)token的登錄認證。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1.在用戶登錄后,如果要訪問其他路徑下的資源的話,我們是否還需要再驗證一遍呢?而且我們登陸上系統(tǒng)長時間不操作的話還需不需要再次驗證?所以這種情況下就很需要token來實現(xiàn)登錄功能。并通過redis(redis是一個key-value存儲系統(tǒng),它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型))來存儲token信息。

功能描述:用戶登錄成功后,后臺返回一個token給調(diào)用者,同時自定義一個@AuthToken注解,被該注解標注的API請求都需要進行token效驗,效驗通過才可以正常訪問,實現(xiàn)接口級的鑒權控制。同時token具有生命周期,在用戶持續(xù)一段時間不進行操作的話,token則會過期,用戶一直操作的話,則不會過期。

?2.流程分析

(1)客戶端登錄,輸入用戶名和密碼,在后端數(shù)據(jù)庫進行驗證,如果驗證失敗則返回登陸失敗的提示。如果成功了則生成token,并將token和用戶名雙向綁定,然后存入redis,同時使用token+username作為key把當前的時間戳存入redis。并設置他們的過期時間。

(2)然后設置攔截器,每一個被@AuthToken注解標注的接口,都要首先檢查客戶端傳過來的Authorization字段,獲取token。由于token與username雙向綁定,可以通過獲取的token來嘗試從redis中獲取username,如果可以獲取則說明token正確,登陸成功;反之,則說明失敗。

(3)token可以根據(jù)用戶的使用時間來動態(tài)的調(diào)整自己的過期時間。在生成 token 的同時也往 redis 里面存入了創(chuàng)建 token 時的時間戳,每次請求被攔截器攔截 token 驗證成功之后,將當前時間與存在 redis 里面的 token 生成時刻的時間戳進行比較,如果當前時間距離創(chuàng)建時間快要到達設置的redis過期時間的話,就重新設置token過期時間,將過期時間延長。如果用戶在設置的 redis 過期時間的時間長度內(nèi)沒有進行任何操作(沒有發(fā)請求),則token會在redis中過期。token過期后則會登陸失敗,重新輸入用戶名和密碼。

3.代碼實現(xiàn):

項目具體結構如下:

Springboot+redis實現(xiàn)token的登錄認證?

首先,先導入依賴:

<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>3.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.2</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.16.22</version>
		</dependency>
<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.54</version>
		</dependency>

自定義注解的實現(xiàn):@Target?說明了Annotation所修飾的對象范圍,表示注解作用在方法和變量上,{ElementType.METHOD, ElementType.TYPE}表示注解作用在方法、類、接口上。

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthToken {

}

然后設置攔截器:

/**
 * @author 旺旺米雪餅
 */
@Slf4j
public class AuthorizationInterceptor implements HandlerInterceptor {

    //存放鑒權信息的Header名稱,默認是Authorization
    private String httpHeaderName = "Authorization";

    //鑒權失敗后返回的錯誤信息,默認為401 unauthorized
    private String unauthorizedErrorMessage = "401 unauthorized";

    //鑒權失敗后返回的HTTP錯誤碼,默認為401
    private int unauthorizedErrorCode = HttpServletResponse.SC_UNAUTHORIZED;

    /**
     * 存放登錄用戶模型Key的Request Key
     */
    public static final String REQUEST_CURRENT_KEY = "REQUEST_CURRENT_KEY";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        // 如果打上了AuthToken注解則需要驗證token
        if (method.getAnnotation(AuthToken.class) != null || handlerMethod.getBeanType().getAnnotation(AuthToken.class) != null) {

//            String token = request.getHeader(httpHeaderName);
            String token = request.getParameter(httpHeaderName);
            log.info("Get token from request is {} ", token);
            String username = "";
            Jedis jedis = new Jedis();
            if (token != null && token.length() != 0) {
                username = jedis.get(token);
                log.info("Get username from Redis is {}", username);
            }
            if (username != null && !username.trim().equals("")) {
                //log.info("token birth time is: {}",jedis.get(username+token));
                Long tokeBirthTime = Long.valueOf(jedis.get(token + username));
                log.info("token Birth time is: {}", tokeBirthTime);
                Long diff = System.currentTimeMillis() - tokeBirthTime;
                log.info("token is exist : {} ms", diff);
                //重新設置Redis中的token過期時間
                if (diff > ConstantKit.TOKEN_RESET_TIME) {
                    jedis.expire(username, ConstantKit.TOKEN_EXPIRE_TIME);
                    jedis.expire(token, ConstantKit.TOKEN_EXPIRE_TIME);
                    log.info("Reset expire time success!");
                    Long newBirthTime = System.currentTimeMillis();
                    jedis.set(token + username, newBirthTime.toString());
                }

                //用完關閉
                jedis.close();
                request.setAttribute(REQUEST_CURRENT_KEY, username);
                return true;
            } else {
                JSONObject jsonObject = new JSONObject();

                PrintWriter out = null;
                try {
                    response.setStatus(unauthorizedErrorCode);
                    response.setContentType(MediaType.APPLICATION_JSON_VALUE);

                    jsonObject.put("code", ((HttpServletResponse) response).getStatus());
                    jsonObject.put("message", HttpStatus.UNAUTHORIZED);
                    out = response.getWriter();
                    out.println(jsonObject);

                    return false;
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (null != out) {
                        out.flush();
                        out.close();
                    }
                }

            }

        }

        request.setAttribute(REQUEST_CURRENT_KEY, null);

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

在工具類中設置token過期時間等信息:

/**
 * @author 旺旺米雪餅
 */
public class ConstantKit {
    /**
     * 設置刪除標志為真
     */
    public static final Integer DEL_FLAG_TRUE = 1;

    /**
     * 設置刪除標志為假
     */
    public static final Integer DEL_FLAG_FALSE = 0;

    /**
     * redis存儲token設置的過期時間,10分鐘
     */
    public static final Integer TOKEN_EXPIRE_TIME = 60 * 10;

    /**
     * 設置可以重置token過期時間的時間界限
     */
    public static final Integer TOKEN_RESET_TIME = 1000 * 100;


}

并且設計Md5加密后的token值:

/**
 * @author 旺旺米雪餅
 */
@Component
public class Md5TokenGenerator {

    public String generate(String... strings) {
        long timestamp = System.currentTimeMillis();
        String tokenMeta = "";
        for (String s : strings) {
            tokenMeta = tokenMeta + s;
        }
        tokenMeta = tokenMeta + timestamp;
        String token = DigestUtils.md5DigestAsHex(tokenMeta.getBytes());
        return token;
    }
}

別忘了在WebConfig中添加攔截器。

最后在controller層中進行驗證:文章來源地址http://www.zghlxwxcb.cn/news/detail-405986.html

@RestController
public class Welcome {

    Logger logger = LoggerFactory.getLogger(Welcome.class);

    @Autowired
    Md5TokenGenerator tokenGenerator;

    @Autowired
    UserMapper userMapper;

    @GetMapping("/welcome")
    public String welcome(){

        return "welcome token authentication";
    }


    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public ResponseTemplate login(String username, String password) {

        logger.info("username:"+username+"      password:"+password);

        User user = userMapper.getUser(username,password);

        logger.info("user:"+user);

        JSONObject result = new JSONObject();
        if (user != null) {

            Jedis jedis = new Jedis();
            String token = tokenGenerator.generate(username, password);
            jedis.set(username, token);
            //設置key生存時間,當key過期時,它會被自動刪除,時間是秒
            jedis.expire(username, ConstantKit.TOKEN_EXPIRE_TIME);
            jedis.set(token, username);
            jedis.expire(token, ConstantKit.TOKEN_EXPIRE_TIME);
            Long currentTime = System.currentTimeMillis();
            jedis.set(token + username, currentTime.toString());

            //用完關閉
            jedis.close();

            result.put("status", "登錄成功");
            result.put("token", token);
        } else {
            result.put("status", "登錄失敗");
        }

        return ResponseTemplate.builder()
                .code(200)
                .message("登錄成功")
                .data(result)
                .build();

    }

    @RequestMapping(value = "test", method = RequestMethod.GET)
    @AuthToken
    public ResponseTemplate test() {

        logger.info("已進入test路徑");

        return ResponseTemplate.builder()
                .code(200)
                .message("Success")
                .data("test url")
                .build();
    }

}

到了這里,關于Springboot+redis實現(xiàn)token的登錄認證的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • SpringSecurity實現(xiàn)前后端分離登錄token認證詳解

    SpringSecurity實現(xiàn)前后端分離登錄token認證詳解

    目錄 1. SpringSecurity概述 1.1 權限框架 1.1.1 Apache Shiro 1.1.2?SpringSecurity 1.1.3?權限框架的選擇 1.2 授權和認證 1.3 SpringSecurity的功能 2.SpringSecurity 實戰(zhàn) 2.1 引入SpringSecurity 2.2 認證 2.2.1 登錄校驗流程 ?2.2.2 SpringSecurity完整流程 ?2.2.3 認證流程詳解 2.3 思路分析 2.4 代碼實戰(zhàn) 2.4.1? 自定義

    2024年02月08日
    瀏覽(86)
  • 使用Token方式實現(xiàn)用戶身份鑒權認證

    使用Token方式實現(xiàn)用戶身份鑒權認證

    Token,也稱為“令牌”,是服務端生成的一串字符串,以作客戶端進行請求的一個令牌,當?shù)谝淮蔚卿浐螅掌魃梢粋€Token便將此Token返回給客戶端,以后客戶端只需帶上這個Token前來請求數(shù)據(jù)即可,無需再次帶上用戶名和密碼。比如如下形式: 39faf62271944fe48c4f1d69be71bc9a 傳

    2024年02月11日
    瀏覽(19)
  • 3-2. SpringBoot項目集成【用戶身份認證】實戰(zhàn) 【實戰(zhàn)核心篇】基于JWT生成和校驗Token

    3-2. SpringBoot項目集成【用戶身份認證】實戰(zhàn) 【實戰(zhàn)核心篇】基于JWT生成和校驗Token

    書接上文 技術選型篇,我們做了【用戶身份認證】的技術選型說明,對基于 Session、Token、JWT 的方案進行了詳細的對比分析,詳細說明了它們都是什么和各自的優(yōu)缺點!這些是實戰(zhàn)的基礎,還沒看過的同學,建議先看上文。最終采用的是目前流行的 基于JWT的Token用戶身份認證

    2023年04月08日
    瀏覽(27)
  • 3-1. SpringBoot項目集成【用戶身份認證】實戰(zhàn) 【技術選型篇】基于Session、Token、JWT怎么選?

    3-1. SpringBoot項目集成【用戶身份認證】實戰(zhàn) 【技術選型篇】基于Session、Token、JWT怎么選?

    通過第二章2-2. SpringBoot API開發(fā)詳解 --SpringMVC注解+封裝結果+支持跨域+打包,我們實現(xiàn)了基于SpringBoot項目的 API接口開發(fā) ,并實現(xiàn) API結果統(tǒng)一封裝、支持跨域請求 等等功能,接下來開始第三章,主要做用戶身份認證,主要實現(xiàn)一套 統(tǒng)一鑒權的用戶身份認證的機制 。 我已經(jīng)提

    2024年01月22日
    瀏覽(26)
  • 為什么使用雙token實現(xiàn)無感刷新用戶認證?

    為什么使用雙token實現(xiàn)無感刷新用戶認證?

    認證機制 :對與單token的認證機制在我們項目中僅使用一個Access Token的訪問令牌進行用戶身份認證和授權的方案處理。 不足之處: 安全性較低(因為只有一個token在客戶端和服務器端之間進行傳遞,一目Acess Token被截獲或者被泄露,攻擊者就會在有效時間內(nèi)完成模擬用戶行為,

    2024年01月18日
    瀏覽(33)
  • jwt+redis實現(xiàn)登錄認證

    jwt+redis實現(xiàn)登錄認證

    項目環(huán)境:spring boot項目 pom.xml引入jwt和redis application.yml配置文件中,對redis進行配置 JwtUtil工具類 登錄的控制器 在前端發(fā)起登錄請求,用戶名和密碼驗證通過后,生成jwt,把jwt字符長的值,存放在redis緩存中,然后把jwt字符串返回到前端。 前端拿到jwt字符串后存在一個變量中

    2024年02月21日
    瀏覽(14)
  • 快速實現(xiàn)用戶認證:使用Python和Flask配合PyJWT生成與解密Token的教程及示例代碼

    這段代碼提供了一個使用 Python 和 Flask 結合 JWT (JSON Web Tokens) 進行用戶認證的簡單框架。它包括了生成 token、解碼 token、檢查用戶狀態(tài)和一個裝飾器函數(shù),用于保護需要認證的路由。下面是對代碼的逐部分解釋: 1. generate_token(user_id) 函數(shù) 這個函數(shù)用于為指定的用戶 ID 生成一

    2024年02月22日
    瀏覽(40)
  • Django用戶認證: 利用Django Auth模塊實現(xiàn)用戶注冊、登錄與登出

    用戶登錄注冊屬于用戶認證的一部分,Django內(nèi)置了一套用戶認證體系,使用起來比較方便,而且支持用戶定制和拓展,足以滿足任何復雜的業(yè)務需求。 Django框架中,用戶權限管理被劃分為三個層次: 用戶 :系統(tǒng)使用者,擁有自己的權限。可被一個或多個用戶組包含。 用戶組

    2023年04月20日
    瀏覽(26)
  • 在springBoot中使用JWT實現(xiàn)1.生成token,2.接收前端token進行身份認證,3.通過token獲取對象信息

    在springBoot中使用JWT實現(xiàn)1.生成token,2.接收前端token進行身份認證,3.通過token獲取對象信息

    第一步:引入依賴 第二步:創(chuàng)建工具類 在until包下創(chuàng)建TokenUntil類,用于生成token 利用id,和password作為參數(shù)生成token JWt為這個包下的對象 第三步:token使用 在向前端返回的數(shù)據(jù)對象中添加token屬性 ?是serve層中調(diào)用工具類方法將生成的token放到返回的數(shù)據(jù)中 注意:這里獲取到

    2024年02月04日
    瀏覽(93)
  • flask框架-認證權限(一):使用g對象存登錄用戶信息,認證權限一起實現(xiàn)

    apps ? ? ? ? -user ? ? ? ? __init__.py authen ? ? ? ?__init__.py ? ? ? ? token.py ext ? ? ? ? __init__.py util.py ? ? ? ?public.py ? ? ? ? __init__.py app.py 依賴包 authen/token.py user/views.py 認證大致的邏輯: 1、用戶登錄時,生成token,前端保存token信息 2、前端發(fā)起請求時,將token攜帶在cook

    2024年02月09日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包