目录
1.单点登录
1.1 简介
1.2 代码
1.2.1 我的理解
1.2.2 代码
一处登录,处处登录。
单点登录示例:xxl-sso: 一个分布式单点登录框架。只需要登录一次就可以访问所有相互信任的应用系统。 拥有"轻量级、分布式、跨域、Cookie+Token均支持、Web+APP均支持"等特性;。现已开放源代码,开箱即用。
sso单点登录即一处登录,处处登录,看了视频之后我的理解是假如用户访问一个页面,后台会进行检测此用户是否登陆过了,如果登录过了则正常访问,如果没有则会跳转到登录页面。
其中用户在登录后,会根据用户登陆的信息生成一个token,用户信息和token会被上传到redis中,同时设置过期时间,同时token也会被存放在cookie中。
当用户再去访问这个页面时,会先判断此用户是否携带token,如果token不为空,则会将用户已经登陆的信息保存在session中,如果为空且后台没有获取到session中用户已经登陆的信息,则会跳转到登录页面,同时携带用户访问此页面的地址,当用户成功登录之后则又会跳转到此地址,如果用户登录信息不为空,则会直接访问此页面。
服务端为8080,客户端为8081,8082。
8080:
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:
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:
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";
}
}
}