SSO单点登录

目录

1.单点登录

1.1 简介

1.2 代码

1.2.1 我的理解

1.2.2 代码


1.单点登录

1.1 简介

SSO单点登录_第1张图片

一处登录,处处登录。

单点登录示例:xxl-sso: 一个分布式单点登录框架。只需要登录一次就可以访问所有相互信任的应用系统。 拥有"轻量级、分布式、跨域、Cookie+Token均支持、Web+APP均支持"等特性;。现已开放源代码,开箱即用。

SSO单点登录_第2张图片

SSO单点登录_第3张图片

1.2 代码

1.2.1 我的理解

sso单点登录即一处登录,处处登录,看了视频之后我的理解是假如用户访问一个页面,后台会进行检测此用户是否登陆过了,如果登录过了则正常访问,如果没有则会跳转到登录页面。

其中用户在登录后,会根据用户登陆的信息生成一个token,用户信息和token会被上传到redis中,同时设置过期时间,同时token也会被存放在cookie中。

当用户再去访问这个页面时,会先判断此用户是否携带token,如果token不为空,则会将用户已经登陆的信息保存在session中,如果为空且后台没有获取到session中用户已经登陆的信息,则会跳转到登录页面,同时携带用户访问此页面的地址,当用户成功登录之后则又会跳转到此地址,如果用户登录信息不为空,则会直接访问此页面。

1.2.2 代码

服务端为8080,客户端为8081,8082。

8080:

SSO单点登录_第4张图片

        
            org.apache.commons
            commons-lang3
            3.7
        

        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        

# 应用服务 WEB 访问端口
server.port=8080

sso.server.url=http://localhost:8080

spring.thymeleaf.cache=false
# 检查模板是否存在,然后再呈现
spring.thymeleaf.check-template=true
# 检查模板位置是否正确(默认值 :true )
spring.thymeleaf.check-template-location=true
#Content-Type 的值(默认值: text/html )
spring.thymeleaf.content-type=text/html
# 开启 MVC Thymeleaf 视图解析(默认值: true )
spring.thymeleaf.enabled=true
# 模板编码
spring.thymeleaf.encoding=UTF-8
# 要被排除在解析之外的视图名称列表,⽤逗号分隔
spring.thymeleaf.excluded-view-names=
# 要运⽤于模板之上的模板模式。另⻅ StandardTemplate-ModeHandlers( 默认值: HTML5)
spring.thymeleaf.mode=HTML5
# 在构建 URL 时添加到视图名称前的前缀(默认值: classpath:/templates/ )
spring.thymeleaf.prefix=classpath:/templates/
# 在构建 URL 时添加到视图名称后的后缀(默认值: .html )
spring.thymeleaf.suffix=.html
spring:
  redis:
    host: 1.155.4
    port: 6379
    password: 123


  
    
    Title
  
  
    
用户名:
密码:
package com.sso.controller;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Controller
public class LoginController {
    @Autowired
    StringRedisTemplate redisTemplate;

    @GetMapping("/userInfo")
    @ResponseBody
    public String userInfo(@RequestParam("token") String token){
        String s = redisTemplate.opsForValue().get(token);
        return s;
    }

    @GetMapping("/login.html")
    public String loginPage(@RequestParam("redirect_url") String url, Model model,@CookieValue(value = "sso_token",required = false) String sso_token) {
        //判断是否登录过?依据是否拥有cookie sso_token,如果有直接返回之前的页面
        if(!StringUtils.isEmpty(sso_token)){
            return "redirect:" + url+"?token="+sso_token;
        }
        model.addAttribute("url", url);
        return "login";
    }

    @PostMapping("/doLogin")
    public String doLogin(@RequestParam("username") String username, @RequestParam("password") String password,
                          @RequestParam("url") String url, HttpServletResponse response) {
        //登录成功跳转,跳回之前的页面
        if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) {
            //保存登录成功的用户,例如redis
            String uuid = UUID.randomUUID().toString().replace("-", "");
            redisTemplate.opsForValue().set(uuid,username,30, TimeUnit.MINUTES);
            Cookie sso_token = new Cookie("sso_token",uuid);
            response.addCookie(sso_token);
            return "redirect:" + url+"?token="+uuid;
        }
        return "login";
    }
}

8081:

SSO单点登录_第5张图片


  org.apache.commons
  commons-lang3
  3.7


  org.springframework.boot
  spring-boot-starter-thymeleaf


  org.springframework.boot
  spring-boot-starter-web



  org.projectlombok
  lombok
  true

# 应用服务 WEB 访问端口
server.port=8081
sso.server.url=http://localhost:8080/login.html

spring.thymeleaf.cache=false
# 检查模板是否存在,然后再呈现
spring.thymeleaf.check-template=true
# 检查模板位置是否正确(默认值 :true )
spring.thymeleaf.check-template-location=true
#Content-Type 的值(默认值: text/html )
spring.thymeleaf.content-type=text/html
# 开启 MVC Thymeleaf 视图解析(默认值: true )
spring.thymeleaf.enabled=true
# 模板编码
spring.thymeleaf.encoding=UTF-8
# 要被排除在解析之外的视图名称列表,⽤逗号分隔
spring.thymeleaf.excluded-view-names=
# 要运⽤于模板之上的模板模式。另⻅ StandardTemplate-ModeHandlers( 默认值: HTML5)
spring.thymeleaf.mode=HTML5
# 在构建 URL 时添加到视图名称前的前缀(默认值: classpath:/templates/ )
spring.thymeleaf.prefix=classpath:/templates/
# 在构建 URL 时添加到视图名称后的后缀(默认值: .html )
spring.thymeleaf.suffix=.html


  
    
    Title
  
  
    

欢迎!我是8081-------------

欢迎你! [[${session.loginUser}]]

  • 姓名:[[${emp}]]
package com.sso.controller;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

@Controller
public class HelloController {

    @Value("${sso.server.url}")
    String ssoServerUrl;
    /**
     * 无需登录即可访问
     * @return
     */
    @ResponseBody
    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }


    /**
     * 可以感知登录服务器登录成功返回
     * ssoserver登录成功返回就会带上token
     * @return
     */
    @GetMapping("/employee")
    public String emploees(Model model, HttpSession session,@RequestParam(value = "token",required = false) String token){
        if(!StringUtils.isEmpty(token)){
            //去sso服务器获取当前token真正对应的用户信息
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity forEntity = restTemplate.getForEntity("http://localhost:8080/userInfo?token=" + token, String.class);
            String body = forEntity.getBody();
            session.setAttribute("loginUser",body);
        }
        Object loginUser = session.getAttribute("loginUser");
        if(loginUser == null){
            //没有登录,跳转到登录服务器进行登录

            return "redirect:"+ssoServerUrl+"?redirect_url=http://localhost:8081/employee";
        }else {
            List emps = new ArrayList();
            emps.add("张三");
            emps.add("李四");
            emps.add("王五");
            model.addAttribute("emps", emps);
            return "list";
        }
    }
}

8082:

SSO单点登录_第6张图片


  org.apache.commons
  commons-lang3
  3.7


  org.springframework.boot
  spring-boot-starter-thymeleaf
server.port=8082
sso.server.url=http://localhost:8080/login.html

# 开启模板缓存(默认值: true )
spring.thymeleaf.cache=true
# 检查模板是否存在,然后再呈现
spring.thymeleaf.check-template=true
# 检查模板位置是否正确(默认值 :true )
spring.thymeleaf.check-template-location=true
#Content-Type 的值(默认值: text/html )
spring.thymeleaf.content-type=text/html
# 开启 MVC Thymeleaf 视图解析(默认值: true )
spring.thymeleaf.enabled=true
# 模板编码
spring.thymeleaf.encoding=UTF-8
# 要被排除在解析之外的视图名称列表,⽤逗号分隔
spring.thymeleaf.excluded-view-names=
# 要运⽤于模板之上的模板模式。另⻅ StandardTemplate-ModeHandlers( 默认值: HTML5)
spring.thymeleaf.mode=HTML5
# 在构建 URL 时添加到视图名称前的前缀(默认值: classpath:/templates/ )
spring.thymeleaf.prefix=classpath:/templates/
# 在构建 URL 时添加到视图名称后的后缀(默认值: .html )
spring.thymeleaf.suffix=.html
# 应用服务 WEB 访问端口





    
    Title


欢迎!我是8082-------------

欢迎你! [[${session.loginUser}]]

  • 姓名:[[${emp}]]
package com.sso.controller;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

@Controller
public class HelloController {

    @Value("${sso.server.url}")
    String ssoServerUrl;
    /**
     * 无需登录即可访问
     * @return
     */
    @ResponseBody
    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }


    /**
     * 可以感知登录服务器登录成功返回
     * ssoserver登录成功返回就会带上token
     * @return
     */
    @GetMapping("/boss")
    public String emploees(Model model, HttpSession session,@RequestParam(value = "token",required = false) String token){
        if(!StringUtils.isEmpty(token)){
            //去sso服务器获取当前token真正对应的用户信息
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity forEntity = restTemplate.getForEntity("http://localhost:8080/userInfo?token=" + token, String.class);
            String body = forEntity.getBody();
            session.setAttribute("loginUser",body);
        }
        Object loginUser = session.getAttribute("loginUser");
        if(loginUser == null){
            //没有登录,跳转到登录服务器进行登录
            return "redirect:"+ssoServerUrl+"?redirect_url=http://localhost:8082/boss";
        }else {
            List emps = new ArrayList();
            emps.add("Jack");
            emps.add("Tom");
            emps.add("Ada");
            model.addAttribute("emps", emps);
            return "list";
        }
    }
}

你可能感兴趣的:(中间件&服务框架,bootstrap,前端,html)