Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >sso单点登录与Jsonp

sso单点登录与Jsonp

作者头像
周杰伦本人
发布于 2023-10-12 06:17:13
发布于 2023-10-12 06:17:13
30700
代码可运行
举报
文章被收录于专栏:同步文章同步文章
运行总次数:0
代码可运行

单点登录与Jsonp

SSO英文全称Single Sign On,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。它是目前比较流行的企业业务整合的解决方案之一。 例如天猫和淘宝 登陆一个网站 另一个网站不需要登陆

单点登录的主要问题在于session共享问题 要对session中进行统一管理 使用tomcat中的session不好管理 因此我们使用redis模拟Session,实现Session的统一管理。

用户注册和传统的一样

用户登录

####用户登录的大体思路:

传入用户名和密码 与数据库中的比对 如果相同 登录成功,生成token(UUID),设置键值 放入redis缓中 并设置过期时间 并把token写入cookie中,其他系统通过取cookie中的token来从redis中得到用户信息,展示用户信息。

####用户登录

ajax调用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
doLogin:function() {
				$.post("/user/login", $("#formlogin").serialize(),function(data){
					if (data.status == 200) {
						jAlert('登录成功!',"提示", function(){
							if (redirectUrl == "") {
								location.href = "http://localhost:8082";
							} else {
								location.href = redirectUrl;
							}
						});
						
					} else {
						jAlert("登录失败,原因是:" + data.msg,"失败");
					}
				});
			}

控制层:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.e3mall.sso.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.e3mall.common.util.CookieUtils;
import cn.e3mall.common.util.E3Result;
import cn.e3mall.sso.service.LoginService;

/**
 * 用户登录处理
 * <p>Title: LoginController</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Controller
public class LoginController {
	
	@Autowired
	private LoginService loginService;
	@Value("${TOKEN_KEY}")
	private String TOKEN_KEY;

	@RequestMapping("/page/login")
	public String showLogin(){
		return "login";
	}
	
	@RequestMapping("/user/login")
	@ResponseBody
	public E3Result login(String username,String password,
			HttpServletRequest request,HttpServletResponse response){
		E3Result e3Result = loginService.userLogin(username, password);
		//判断是否登录成功
		if (e3Result.getStatus()==200) {
			String token = e3Result.getData().toString();
			//如果登录成功 把token写入cookie
			CookieUtils.setCookie(request, response, TOKEN_KEY, token);
		}
		return e3Result;
	}
}

service层:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.e3mall.sso.service.impl;

import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import cn.e3mall.common.jedis.JedisClient;
import cn.e3mall.common.util.E3Result;
import cn.e3mall.common.util.JsonUtils;
import cn.e3mall.mapper.TbUserMapper;
import cn.e3mall.pojo.TbUser;
import cn.e3mall.pojo.TbUserExample;
import cn.e3mall.pojo.TbUserExample.Criteria;
import cn.e3mall.sso.service.LoginService;

/**
 * 用户登录处理
 * <p>Title: LoginServiceImpl</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Service
public class LoginServiceImpl implements LoginService {
	
	@Autowired
	private TbUserMapper userMapper;
	@Autowired
	private JedisClient jedisClient;
	@Value("${SESSION_EXPIRE}")
	private Integer SESSION_EXPIRE;

	@Override
	public E3Result userLogin(String username, String password) {
//		1.判断用户名密码是否正确
		//根据用户名查询用户信息
		TbUserExample example = new TbUserExample();
		Criteria criteria = example.createCriteria();
		criteria.andUsernameEqualTo(username);
		List<TbUser> list = userMapper.selectByExample(example);
		if (list==null || list.size()==0) {
			//返回用户登录失败
			return E3Result.build(400, "用户名或密码错误");
		}
		//取用户信息
		TbUser user = list.get(0);
		//判断密码是否正确
		if (!DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())) {
			//2.如果不正确 返回登录失败
			return E3Result.build(400, "用户名或密码错误");
		}
//		3.正确生成token(SessionId)
		String token = UUID.randomUUID().toString();
//		4.把用户信息写入Redis key:token value:用户信息
		user.setPassword(null);
		jedisClient.set("SESSION:"+token, JsonUtils.objectToJson(user));
//		5. 设置session过期时间
		jedisClient.expire("SESSION:"+token, SESSION_EXPIRE);
//		6.把token返回
		return E3Result.ok(token);
	}

}

其中代码中用的jedis

https://cloud.tencent.com/developer/article/2338897

CookieUtils工具类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.e3mall.common.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 
 * Cookie 工具类
 *
 */
public final class CookieUtils {

    /**
     * 得到Cookie的值, 不编码
     * 
     * @param request
     * @param cookieName
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName) {
        return getCookieValue(request, cookieName, false);
    }

    /**
     * 得到Cookie的值,
     * 
     * @param request
     * @param cookieName
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    if (isDecoder) {
                        retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
                    } else {
                        retValue = cookieList[i].getValue();
                    }
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return retValue;
    }

    /**
     * 得到Cookie的值,
     * 
     * @param request
     * @param cookieName
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
        	 e.printStackTrace();
        }
        return retValue;
    }

    /**
     * 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue) {
        setCookie(request, response, cookieName, cookieValue, -1);
    }

    /**
     * 设置Cookie的值 在指定时间内生效,但不编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage) {
        setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
    }

    /**
     * 设置Cookie的值 不设置生效时间,但编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, boolean isEncode) {
        setCookie(request, response, cookieName, cookieValue, -1, isEncode);
    }

    /**
     * 设置Cookie的值 在指定时间内生效, 编码参数
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage, boolean isEncode) {
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
    }

    /**
     * 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage, String encodeString) {
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
    }

    /**
     * 删除Cookie带cookie域名
     */
    public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName) {
        doSetCookie(request, response, cookieName, "", -1, false);
    }

    /**
     * 设置Cookie的值,并使其在指定时间内生效
     * 
     * @param cookieMaxage cookie生效的最大秒数
     */
    private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else if (isEncode) {
                cookieValue = URLEncoder.encode(cookieValue, "utf-8");
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {// 设置域名的cookie
            	String domainName = getDomainName(request);
            	System.out.println(domainName);
                if (!"localhost".equals(domainName)) {
                	cookie.setDomain(domainName);
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
        	 e.printStackTrace();
        }
    }

    /**
     * 设置Cookie的值,并使其在指定时间内生效
     * 
     * @param cookieMaxage cookie生效的最大秒数
     */
    private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else {
                cookieValue = URLEncoder.encode(cookieValue, encodeString);
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {// 设置域名的cookie
            	String domainName = getDomainName(request);
            	System.out.println(domainName);
                if (!"localhost".equals(domainName)) {
                	cookie.setDomain(domainName);
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
        	 e.printStackTrace();
        }
    }

    /**
     * 得到cookie的域名
     */
    private static final String getDomainName(HttpServletRequest request) {
        String domainName = null;

        String serverName = request.getRequestURL().toString();
        if (serverName == null || serverName.equals("")) {
            domainName = "";
        } else {
            serverName = serverName.toLowerCase();
            serverName = serverName.substring(7);
            final int end = serverName.indexOf("/");
            serverName = serverName.substring(0, end);
            final String[] domains = serverName.split("\\.");
            int len = domains.length;
            if (len > 3) {
                // www.xxx.com.cn
                domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
            } else if (len <= 3 && len > 1) {
                // xxx.com or xxx.cn
                domainName = "." + domains[len - 2] + "." + domains[len - 1];
            } else {
                domainName = serverName;
            }
        }

        if (domainName != null && domainName.indexOf(":") > 0) {
            String[] ary = domainName.split("\\:");
            domainName = ary[0];
        }
        return domainName;
    }

}

service层的resource.properties配置文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#session过期时间
SESSION_EXPIRE=1800

controller层的resource.properties配置文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#cookie中保存token的key
TOKEN_KEY=token
其他系统显示用户信息

跨域调用单点登录系统的方法进行获取信息 用jsonp实现

Js不可以跨域请求数据。

什么是跨域:

1、域名不同

2、域名相同端口不同。

解决js的跨域问题可以使用jsonp。

Jsonp不是新技术,跨域的解决方案。使用js的特性绕过跨域请求。Js可以跨域加载js文件。

其他系统调用单点登录的js文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var E3MALL = {
	checkLogin : function(){
		var _ticket = $.cookie("token");
		if(!_ticket){
			return ;
		}
		$.ajax({
			url : "http://localhost:8088/user/token/" + _ticket,
			dataType : "jsonp",
			type : "GET",
			success : function(data){
				if(data.status == 200){
					var username = data.data.username;
					var html = username + ",欢迎来到宜立方购物网!<a href=\"http://www.e3mall.cn/user/logout.html\" class=\"link-logout\">[退出]</a>";
					$("#loginbar").html(html);
				}
			}
		});
	}
}

$(function(){
	// 查看是否已经登录,如果已经登录查询登录信息
	E3MALL.checkLogin();
});

单点登录控制层:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.e3mall.sso.controller;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.e3mall.common.util.E3Result;
import cn.e3mall.common.util.JsonUtils;
import cn.e3mall.sso.service.TokenService;

/**
 * 根据token取用户信息Controller
 * <p>Title: TokenController</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Controller
public class TokenController {
	
	@Autowired
	private TokenService tokenService;
	
	//spring4.1用这个版本可以
//	@RequestMapping(value="/user/token/{token}",produces=MediaType.APPLICATION_JSON_UTF8_VALUE)
//	@ResponseBody
//	public String getUserByToken(@PathVariable String token,String callback){
//		E3Result result = tokenService.getUserByToken(token);
//		//判断是否为jsonp请求
//		if (StringUtils.isNotBlank(callback)) {
//			//把结果封装成js语句响应
//			return callback+"("+JsonUtils.objectToJson(result)+");";
//		}
//		return JsonUtils.objectToJson(result);
//	}
	
	//不支持spring4.1之前的版本
	@RequestMapping(value="/user/token/{token}")
	@ResponseBody
	public Object getUserByToken(@PathVariable String token,String callback){
		E3Result result = tokenService.getUserByToken(token);
		//判断是否为jsonp请求
		if (StringUtils.isNotBlank(callback)) {
			//把结果封装成js语句响应
			MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(result);
			mappingJacksonValue.setJsonpFunction(callback);
			return mappingJacksonValue;
		}
		return result;
	}
}

单点登录Service层

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.e3mall.sso.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import cn.e3mall.common.jedis.JedisClient;
import cn.e3mall.common.util.E3Result;
import cn.e3mall.common.util.JsonUtils;
import cn.e3mall.pojo.TbUser;
import cn.e3mall.sso.service.TokenService;

/**
 * 根据token取用户信息
 * <p>Title: TokenServiceImpl</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Service
public class TokenServiceImpl implements TokenService {

	@Autowired
	private JedisClient jedisClient;
	@Value("${SESSION_EXPIRE}")
	private Integer SESSION_EXPIRE;
	
	@Override
	public E3Result getUserByToken(String token) {
		//根据token到redis中取用户信息
		String json = jedisClient.get("SESSION:"+token);
		//取不到用户信息 登录已经过期 返回登录过期
		if (StringUtils.isBlank(json)) {
			return E3Result.build(201, "用户登录已经过期");
		}
		//取到用户信息更新token的过期时间
		jedisClient.expire("SESSION:"+token, SESSION_EXPIRE);
		//返回结果,E3Result其中包含TbUser对象
		TbUser user = JsonUtils.jsonToPojo(json, TbUser.class);
		return E3Result.ok(user);
	}

}
登出

需要根据token删除redis中的key。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
sso单点登录的入门(Session跨域、Spring-Session共享)
1、单点登录,就是多系统,单一位置登录,实现多系统同时登录的一种技术。单点登录一般是用于互相授信的系统,实现单一位置登录,全系统有效的。
别先生
2019/07/27
2K0
基于SpringBoot+JWT+Redis跨域单点登录的实现
项目中涉及到单点登录,通过各方面了解和学习,本篇就来记录下个人对单点登录的理解和实现;当然对于不同的业务场景,单点登录的实现方式可能不同,但是核心思想应该都是差不多的.....
AI码真香
2022/09/13
2.6K0
基于SpringBoot+JWT+Redis跨域单点登录的实现
Java工具集-Cookie工具类
添加依赖 <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> 代码示例 package com.simple.util.http; import javax.servlet.http.Cookie; i
cwl_java
2020/02/11
1.5K0
Java后端Cookie工具类(设置Cookie有效时间、得到Cookie的域名等方法)
在这里总结一些后端处理Cookie的工具类方法,供参考 调用就可以这样 // 设置cookie CookieUtils.setCookie(request, response, "user", JSONObject.toJSONString(usersVO), true); // 清除cookie CookieUtils.deleteCookie(request, response, "user"); 工具类如下: public final class CookieUtils { final s
砖业洋__
2023/05/06
1.6K0
Web阶段:第十六章:Cookie技术
Cookie技术 a)**什么是Cookie?** 1.Cookie翻译过来是饼干的意思。 2.Cookie是由服务器通知客户端,并由客户端保存键值对的一种技术。 它的构造器是:public Cook
Java廖志伟
2022/09/28
3140
Web阶段:第十六章:Cookie技术
Java常用工具类整合
CSDN加速:https://codechina.csdn.net/mirrors/evil0ps/utils 源码和jar见:https://github.com/evil0ps/utils
JokerDJ
2023/11/27
3390
SSO 单点登录_sso登陆
domain2 与 domain1 区别不大,只需将 1 复制一份,将 1 改为 2 即可。
全栈程序员站长
2022/11/01
1.2K0
SSO 单点登录_sso登陆
redis实现单点登录原理(spring ioc和aop原理及应用场合)
单点登录功能分析 请求的url:/user/login 请求的方法:POST 参数:username、password,表单提交的数据。可以使用方法的形参接收。 返回值:json数据,包含一个token。 业务逻辑: 登录的业务流程:
全栈程序员站长
2022/07/27
1.2K0
redis实现单点登录原理(spring ioc和aop原理及应用场合)
单点登录(SSO) - 崔笑颜的博客
单点登录又称之为Single Sign On,简称SSO,单点登录可以通过基于用户会话的共享,他分文两种,先来看第一种,那就是他的原理是分布式会话来实现。
崔笑颜
2021/02/02
9160
什么是单点登录(SSO)
在前阵子有个读者来我这投稿,是使用JWT实现单点登录的(但是文章中并没有介绍什么是单点登录),所以我觉得是时候来整理一下了。
Java3y
2019/05/17
1.6K0
什么是单点登录(SSO)
比如阿里系的淘宝和天猫,很明显地我们可以知道这是两个系统,但是你在使用的时候,登录了天猫,淘宝也会自动登录。
Java团长
2019/05/17
1.1K1
单点登录系统实现
单点登录系统实现基于SpringBoot 今天的干货有点湿,里面夹杂着我的泪水。可能也只有代码才能让我暂时的平静。通过本章内容你将学到单点登录系统和传统登录系统的区别,单点登录系统设计思路,Sprin
前端教程
2018/03/05
4.6K0
单点登录系统实现
sso系统使用
一:什么是sso(single sign on) ?    sso(单点登录系统)简单说就是客户端第一次访问应用1的时候,由于没有登录,会被引导到登录页面进行登录,如果登录校验通过,将返回一个认证信息
用户2146856
2018/05/18
9610
基于SpringBoot实现单点登录系统
单点登录系统设计思路:采用Spring4 Java配置方式整合HttpClient,Redis ,MySql和SpringBoot的简易教程。
JAVA葵花宝典
2021/01/04
2.2K0
基于SpringBoot实现单点登录系统
day78_淘淘商城项目_11_单点登录系统实现 + 用户名回显 + ajax请求跨域问题详解_匠心笔记
SSO系统就是解决分布式环境下登录问题的,本质上是解决分布式环境下Session共享问题。
黑泽君
2018/12/24
1.3K0
JWT单点登录[通俗易懂]
SSO(Single Sign On)SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
全栈程序员站长
2022/08/25
2.1K0
JWT单点登录[通俗易懂]
单点登录
SSO英文全称Single Sign On,单点登录; SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
周杰伦本人
2022/10/25
1.3K0
单点登录
购物车的原理以及实现
  今天模拟京东的购物车实现原理完成了购物车模块的开发, 给大家分享下。 京东的购物车实现原理:在用户登录和不登录的状态下对购物车存入cookie还是持久化到redis中的实现。下面就来具体说次购物车的实现过程 两种情况: 用户登录,购物车存入redis中 用户未登录,购物车存入cookie中 比较两种方式的优缺点:  cookie:优点:数据保存在用户浏览器中,不占用服务端内存;用户体检效果好;代码实现简单      缺点:cookie的存储空间只有4k;更换设备时,购物车信息不能同步;cookie禁用,
用户2146856
2018/05/18
2.4K0
10_单点登录SSO
在企业发展初期,企业使用的系统很少,通常一个或者两个,每个系统都有自己的登录模块,运营人员每天用自己 的账号登录,很方便。但随着企业的发展,用到的系统随之增多,运营人员在操作不同的系统时,需要多次登录, 而且每个系统的账号都不一样,这对于运营人员来说,很不方便。于是,就想到是不是可以在一个系统登录,其他系统就不用登录了呢?这就是单点登录要解决的问题。
全栈程序员站长
2022/09/12
9980
10_单点登录SSO
搞懂单点登录SSO,基于SpringBoot+JWT实现单点登录解决方案
单点登录是目前比较流行的企业业务整合的解决方案之一。单点登录是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。例如:百度旗下有很多的产品,比如百度贴吧、百度知道、百度文库等,只要登录百度账号,在任何一个地方都是已登录状态,不需要重新登录。
架构师精进
2023/10/06
10.3K0
搞懂单点登录SSO,基于SpringBoot+JWT实现单点登录解决方案
相关推荐
sso单点登录的入门(Session跨域、Spring-Session共享)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验