欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot集成redis與session實(shí)現(xiàn)分布式單點(diǎn)登錄

 更新時(shí)間:2022年09月23日 11:27:34   作者:晚上睡不著_  
這篇文章主要介紹了SpringBoot集成redis與session實(shí)現(xiàn)分布式單點(diǎn)登錄,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

前言:

由于考慮到cookie的安全性問題,就有了下面這個(gè)版本的sso

單點(diǎn)登錄 SSO(Single Sign On)

什么是單點(diǎn)登錄?

單點(diǎn)登錄的英文名叫做:Single Sign On(簡稱SSO),指在同一帳號平臺下的多個(gè)應(yīng)用系統(tǒng)中,用戶只需登錄一次,即可訪問所有相互信任的系統(tǒng)。簡而言之,多個(gè)系統(tǒng),統(tǒng)一登陸。

我們可以這樣理解,在一個(gè)服務(wù)模塊登錄后,其他模塊無需再登錄

實(shí)現(xiàn)方式

  • session廣播機(jī)制實(shí)現(xiàn)(老方法) ? 當(dāng)模塊較多時(shí),比較浪費(fèi)資源;數(shù)據(jù)冗余,存在多份一樣的數(shù)據(jù)? session默認(rèn)過期時(shí)間30分鐘
  • 基于cookie+redis實(shí)現(xiàn)? 在項(xiàng)目中任何一個(gè)模塊登錄后,把數(shù)據(jù)放到兩個(gè)地方? redis:key:生成唯一隨機(jī)值(ip、用戶id等) value:用戶數(shù)據(jù)? cookie:存放redis生成的key值放到cookie? 訪問其他模塊,發(fā)送請求帶著cookie進(jìn)行發(fā)送,服務(wù)器獲取cookie值,在redis中查詢,根據(jù)key進(jìn)行查詢,如果找到就是登錄狀態(tài)
  • 分布式session方式實(shí)現(xiàn)單點(diǎn)登錄流程運(yùn)行:(1) 用戶第一次登錄時(shí),將會話信息(用戶Id和用戶信息),比如以用戶Id為Key,寫入分布式Session;(2) 用戶再次登錄時(shí),獲取分布式Session,是否有會話信息,如果沒有則調(diào)到登錄頁;(3) 一般采用Cache中間件實(shí)現(xiàn),建議使用Redis,因此它有持久化功能,方便分布式Session宕機(jī)后,可以從持久化存儲中加載會話信息;(4) 存入會話時(shí),可以設(shè)置會話保持的時(shí)間,比如15分鐘,超過后自動超時(shí);結(jié)合Cache中間件,實(shí)現(xiàn)的分布式Session,可以很好的模擬Session會話。
  • token驗(yàn)證在項(xiàng)目某個(gè)模塊進(jìn)行登錄,登錄之后,按照jwt規(guī)則生成字待串,把登錄之后用戶包含到生成字符串里面,把字符串返回
    (1)可以把字符串通過cookie返回
    (2)把字符串通過地址欄返回前端收到token之后將token存儲在自己的請求頭之中或者url后面,這樣每次請求都可以帶著token請求。再去訪問項(xiàng)目其他模塊,獲取地址欄或者請求頭里面的token,根據(jù)字符串獲取用戶信息。同時(shí)為了設(shè)置失效時(shí)間,可以將token放在redis中,設(shè)置失效時(shí)間,判斷過期。
  • CAS 中央認(rèn)證服務(wù)

開發(fā)技術(shù)

  • SpringBoot
  • Redis
  • Session

單點(diǎn)登錄實(shí)現(xiàn)流程

  • 用戶在登錄時(shí),登錄成功以后得到當(dāng)前sessionid
  • 將用戶信息存儲在redis里面,設(shè)置有效時(shí)間30分鐘,以key-value形式,sessionid作為key,登錄成功后的用戶信息作為value
  • 訪問時(shí)通過攔截器攔截請求,判斷當(dāng)前sessionid是否在redis里,再則延長壽命,不再提示身份過期
  • 完成登錄驗(yàn)證后,放行執(zhí)行訪問請求

實(shí)現(xiàn)案例

實(shí)現(xiàn)效果:使用nginx做輪詢分發(fā)請求,在任何一個(gè)服務(wù)登錄成功以后,在訪問其他服務(wù)時(shí)就不需要再去登錄

  • 1,首先創(chuàng)建一個(gè)boot項(xiàng)目
  • 2,導(dǎo)入pom依賴
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>

3,配置核心文件

注意:這里只有一個(gè)配置文件,若想啟動兩個(gè)端口。就在編輯頁面的  VM OPTIONS 里配置如下 -Dserver.port=8082

server:
  port: 8081
## redis
#session存儲類型
spring:
  application:
    name: redis_cookie
  redis:
    host: 127.0.0.1
    port: 6379
    #沒用就填空
    password:
    jedis:
      pool:
        #連接池最大連接數(shù)
        max-active: 8
        #阻塞時(shí)間 (負(fù)表示沒有)
        max-wait: -1
        #最大空閑連接
        max-idle: 8
        #最小空閑連接
        min-idle: 0
    #連接超時(shí)時(shí)間
    timeout: 30000
    database: 0

4,編寫用戶類

package com.gxhh.redis_session.bean;

/**
 * @Program: LoginDemo
 * @ClassName User
 * @Description: 用戶類
 * @Author: liutao
 * @Create: 2022/7/8 16:04
 * @Version: 1.0
 */
public class User {
    private String username;
    private String pwd;

    public User() {

    }
    public User(String username, String pwd) {
        this.username = username;
        this.pwd = pwd;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + ''' +
                ", pwd='" + pwd + ''' +
                '}';
    }
}

5,編寫登錄接口和業(yè)務(wù)邏輯

package com.gxhh.redis_session.web;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gxhh.redis_session.bean.User;
import com.gxhh.redis_session.utils.CookieUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
 * @Program: redis_cookie
 * @ClassName LoginController
 * @Author: liutao
 * @Description: 用戶登錄和測試接口
 * @Create: 2022-07-09 19:50
 * @Version 1.0
 **/
@RestController
public class LoginController {
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    CookieUtil CookieUtil;

    @Value("${server.port}")
    String port;
    /**
     * 登錄接口
     * @param user User對象
     * @return 提示信息
     * @throws JsonProcessingException
     */
    @PostMapping(value = "/doLogin", produces = "text/html;charset=utf-8")
    public String login(HttpServletRequest request, HttpServletResponse response, User user) throws JsonProcessingException {
        System.out.println(user);
        ValueOperations ops = redisTemplate.opsForValue();
        String s = request.getSession().getId();
            if (redisTemplate.hasKey(s)) {//登錄過
                    return "重復(fù)登錄";
            } else {//未登錄
                if ("sso".equals(user.getUsername()) && "123456".equals(user.getPwd())) {
                    ObjectMapper om = new ObjectMapper();
                    ops.set(s, om.writeValueAsString(user));//將憑證存入Redis
                    redisTemplate.expire(s, 30, TimeUnit.MINUTES);//設(shè)置過期時(shí)間,30分鐘
                    return "登錄成功";
                }else {
                    return "登錄失?。?;
                }
            }
    }

    /**
     * 退出接口
     * @return
     * @throws JsonProcessingException
     */
    @RequestMapping (value = "/logout", produces = "text/html;charset=utf-8")
    public String logout(HttpServletRequest request, HttpServletResponse response, User user) throws JsonProcessingException {
            System.out.println(user);
            if(redisTemplate.delete(request.getSession().getId())){
                request.getSession().invalidate();
                return "成功退出,請登錄!";
            }else {
                return "系統(tǒng)異常!";
            }
    }
    /**
     * 測試接口
     * @param
     * @return
     */
    @GetMapping("/hello")
    public String hello(){
        return "hello 我是端口"+port;
    }
}

6,配置WebMVC攔截器,攔截所有請求,只放行登錄接口

package com.gxhh.redis_session.config;
import com.gxhh.redis_session.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @Program: redis_cookie
 * @ClassName WebMVCConfig
 * @Author: liutao
 * @Description: WebMVC攔截器
 * @Create: 2022-07-09 19:50
 * @Version 1.0
 **/
@Configuration
public class WebMVCConfig  implements WebMvcConfigurer  {
    @Autowired
    LoginInterceptor loginInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")//需要攔截的路徑
                .excludePathPatterns("/doLogin","/login.html") ;//排除/doLogin路徑

    }


}

7,配置請求攔截器

package com.gxhh.redis_session.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gxhh.redis_session.utils.CookieUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

/**
 * @Program: redis_cookie
 * @ClassName LoginInterceptor
 * @Author: liutao
 * @Description: 用戶登錄攔截器,校驗(yàn)session,身份驗(yàn)證
 * @Create: 2022-07-09 19:50
 * @Version 1.0
 **/
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    CookieUtil CookieUtil;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("攔截到請求:"+request.getRequestURI());
        System.out.println("當(dāng)前令牌:"+request.getSession().getId());
        String s = request.getSession().getId();
        System.out.println("登錄狀態(tài):"+redisTemplate.hasKey(s));
        if (redisTemplate.hasKey(s)) {//延長登錄狀態(tài)
            redisTemplate.expire(s, 30, TimeUnit.MINUTES);//設(shè)置過期時(shí)間,30分鐘
            return true;
        }else {//身份過期
            response.setContentType("text/html;charset=utf-8");
            PrintWriter out = response.getWriter();
            out.write("身份過期,非法請求");
            return false;
        }
    }
}

8,nginx分發(fā)輪詢配置

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    #access_log  logs/access.log  main;
    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;
    #gzip  on;
    upstream mysvr{
        server localhost:8081;
        server localhost:8082;
    }
    server {
        listen       8052;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        #  location / {
        #     root   html;
        #     index  index.html index.htm;
        #     proxy_pass http://localhost:8011;
        # }
        location / {
            # root   html;
            # index  index.html index.htm;
            proxy_pass http://mysvr;
        }
        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ .php$ {
        #    proxy_pass   http://127.0.0.1;
        #}
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ .php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /.ht {
        #    deny  all;
        #}
    }

看效果

先訪問測試接口:

然后再登錄:

訪問測試接口:

關(guān)閉瀏覽器后訪問:

到此這篇關(guān)于SpringBoot集成redis與session實(shí)現(xiàn)分布式單點(diǎn)登錄的文章就介紹到這了,更多相關(guān)SpringBoot集成redis 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 新手小白學(xué)JAVA 日期類Date SimpleDateFormat Calendar(入門)

    新手小白學(xué)JAVA 日期類Date SimpleDateFormat Calendar(入門)

    本文主要介紹了JAVA 日期類Date SimpleDateFormat Calendar,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • java判斷用戶輸入的是否至少含有N位小數(shù)的實(shí)例

    java判斷用戶輸入的是否至少含有N位小數(shù)的實(shí)例

    下面小編就為大家分享一篇java判斷用戶輸入的是否至少含有N位小數(shù)的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • Java并發(fā)編程之Semaphore詳解

    Java并發(fā)編程之Semaphore詳解

    這篇文章主要介紹了Java并發(fā)編程之concurrent包中的Semaphore詳解,信號量Semaphore一般用來表示可用資源的個(gè)數(shù),相當(dāng)于一個(gè)計(jì)數(shù)器,可類比生活中停車場牌子上面顯示的停車場剩余車位數(shù)量,需要的朋友可以參考下
    2023-12-12
  • Spring事務(wù)傳播屬性和隔離級別詳細(xì)介紹

    Spring事務(wù)傳播屬性和隔離級別詳細(xì)介紹

    這篇文章主要介紹了Spring事務(wù)傳播屬性和隔離級別詳細(xì)介紹,同時(shí)涉及傳播行為介紹,超時(shí)設(shè)置等相關(guān)內(nèi)容,需要的朋友可以參考下。
    2017-09-09
  • 詳解Java分布式事務(wù)的 6 種解決方案

    詳解Java分布式事務(wù)的 6 種解決方案

    在分布式系統(tǒng)、微服務(wù)架構(gòu)大行其道的今天,服務(wù)間互相調(diào)用出現(xiàn)失敗已經(jīng)成為常態(tài),本文側(cè)重于其他幾項(xiàng),關(guān)于 2PC、3PC 傳統(tǒng)事務(wù),網(wǎng)上資料已經(jīng)非常多了,這里不多做重復(fù),本文通過示例給大家介紹Java分布式事務(wù)的 6 種解決方案,一起看看吧
    2021-06-06
  • 淺談一下maven優(yōu)缺點(diǎn)及使用和特點(diǎn)

    淺談一下maven優(yōu)缺點(diǎn)及使用和特點(diǎn)

    這篇文章主要介紹了淺談一下maven優(yōu)缺點(diǎn)及使用和特點(diǎn),一個(gè)項(xiàng)目管理工具軟件,那么maven項(xiàng)目有什么優(yōu)缺點(diǎn)呢,讓我們一起來看看吧
    2023-03-03
  • 詳解JAVAEE——SSH三大框架整合(spring+struts2+hibernate)

    詳解JAVAEE——SSH三大框架整合(spring+struts2+hibernate)

    這篇文章主要介紹了詳解JAVAEE——SSH三大框架整合(spring+struts2+hibernate),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Java中兩個(gè)大數(shù)之間的相關(guān)運(yùn)算及BigInteger代碼示例

    Java中兩個(gè)大數(shù)之間的相關(guān)運(yùn)算及BigInteger代碼示例

    這篇文章主要介紹了Java中兩個(gè)大數(shù)之間的相關(guān)運(yùn)算及BigInteger代碼示例,通過biginteger類實(shí)現(xiàn)大數(shù)的運(yùn)算代碼,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • SpringBoot配置全局異常處理器捕獲異常詳解

    SpringBoot配置全局異常處理器捕獲異常詳解

    spring-boot統(tǒng)一異常捕獲,異常時(shí)相對于return的一種退出機(jī)制,可以由系統(tǒng)觸發(fā),下面這篇文章主要給大家介紹了關(guān)于SpringBoot配置全局異常處理器捕獲異常的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • Java實(shí)現(xiàn)簡易圖書借閱系統(tǒng)

    Java實(shí)現(xiàn)簡易圖書借閱系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡易圖書借閱系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評論