XXL-SSO单点登录___志伟一点心得,整合APP手机端+PC端

一开始很排斥XXL-SSO,没办法每当接触新的技术就感到很吃力,就像去年用Python写爬虫一样,一周才学会爬虫,废话不多说,直接上干货
从guthub上获取XXL-SSO源码(后来才知道XXL是作者徐雪里的简写),直接下载下来就能用,
github地址
毕竟是开源的,好处比较多,来来来,上度娘

1、简洁:API直观简洁,可快速上手;
2、轻量级:环境依赖小,部署与接入成本较低;
3、单点登录:只需要登录一次就可以访问所有相互信任的应用系统。
4、分布式:接入SSO认证中心的应用,支持分布式部署;
5、HA:Server端与Client端,均支持集群部署,提高系统可用性;
6、跨域:支持跨域应用接入SSO认证中心;
7、Cookie+Token均支持:支持基于Cookie和基于Token两种接入方式,并均提供Sample项目;
8、Web+APP均支持:支持Web和APP接入;
9、实时性:系统登陆、注销状态,全部Server与Client端实时共享;
10、CS结构:基于CS结构,包括Server"认证中心"与Client"受保护应用";
11、记住密码:未记住密码时,关闭浏览器则登录态失效;记住密码时,支持登录态自动延期,在自定义延期时间的基础上,原则上可以无限延期;
12、路径排除:支持自定义多个排除路径,支持Ant表达式。用于排除SSO客户端不需要过滤的路径;

其中源码中有几个比较重要的包,解释下

  • xxl-sso-server:中央认证服务,支持集群;
  • xxl-sso-core:Client端依赖;
  • xxl-sso-samples:单点登陆Client端接入示例项目;
    • xxl-sso-web-sample-springboot:基于Cookie接入方式,供用户浏览器访问,springboot版本
    • xxl-sso-token-sample-springboot:基于Token接入方式,常用于无法使用Cookie的场景使用,如APP、Cookie被禁用等,springboot版本

这三个包写的很清楚了,具体用处什么的,还有就是需要理解下面几个概念

sso-server:中央认证服务
sso-client:接入 sso 认证中心的客户端应用
sso-sessionId:登陆用户会话ID,SSO 登陆成功后为用户自动分配
sso-user:登陆用户信息,与 SSO sessionId 相对应

这个是重点,都说有了思想才有代码,
登陆流程剖析:

  1. 客户端访问受限资源时,将会自动重定向到 SSO Server 进入统一登录界面
  2. 用户登录成功之后将会为用户分配 SSO SessionId 并重定向返回来源客户端端应用,同时附带分配的 SSO SessionId
  3. 在客户端的 SSO 过滤器里验证 SSO SessionId 无误,将 SSO SessionId 写入到用户浏览器客户端域名下 cookie 中
  4. SSO 过滤器验证 SSO SessionId 通过,受限资源请求放行

这些看一遍有个印象,到最后项目搭建好测试成功之后再看就有种恍然大悟的感觉
开始搭建项目
第一:引入依赖

<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-sso-core</artifactId>
    <version>${最新稳定版}</version>
</dependency>

第二:项目启动Spring注入bean

@Bean
public FilterRegistrationBean xxlSsoFilterRegistration() {

    // xxl-sso, redis init
    JedisUtil.init(xxlSsoRedisAddress);

    // xxl-sso, filter init
    FilterRegistrationBean registration = new FilterRegistrationBean();

    registration.setName("XxlSsoWebFilter");
    registration.setOrder(1);
    registration.addUrlPatterns("/*");
    registration.setFilter(new XxlSsoWebFilter());
    registration.addInitParameter(Conf.SSO_SERVER, xxlSsoServer);
    registration.addInitParameter(Conf.SSO_LOGOUT_PATH, xxlSsoLogoutPath);

    return registration;
}

这里要注意的是WebFilter,如果你的项目是前后端分离的话直接引入TokenFilter,当然也可以App+前后端不分离的那就注入两个Bean,下面是TokenFilter

 @Bean
    public FilterRegistrationBean<HnyfkjSsoTokenFilter> hnyfkjSsoTokenFilterRegistration() {

        // hnyfkj-sso, redis init
        JedisUtil.init(hnyfkjSsoRedisAddress);

        // hnyfkj-sso, filter init
        FilterRegistrationBean<HnyfkjSsoTokenFilter> registration = new FilterRegistrationBean<>();

        registration.setName("HnyfkjSsoTokenFilter");
        registration.setOrder(1);
        registration.addUrlPatterns("/*");
        registration.setFilter(new HnyfkjSsoTokenFilter());
        registration.addInitParameter(Conf.SSO_SERVER, hnyfkjSsoServer);
        registration.addInitParameter(Conf.SSO_LOGOUT_PATH, hnyfkjSsoLogoutPath);
        registration.addInitParameter(Conf.SSO_EXCLUDED_PATHS, hnyfkjSsoExcludedPaths);

        return registration;
    }

一开始只注入一个Bean,所以一直用app接口去掉,每次都是sso未登录,这是一点容易犯的错,注入两个过滤器之后,两个过滤器,每次都过滤两遍,试想下,手机端也要经过Web端过滤,那也永远都无法访问,因为APP端和Web端不同的是请求头带有token值的,而Web端则是存在Cookie中,所以在过滤器中加一个条件,判断下就可以了,下面在过滤器进入的时候写的,可能我的办法也不是唯一的,判断APP和PC端有别的办法也可以

String webHeader = req.getHeader(Conf.SSO_SESSIONID);
		if (!StringUtils.hasLength(webHeader)) {
			chain.doFilter(request, response);
			return;
		}

这个在tokenFilter里面写的,请求头中是空的话就跳转下一个过滤器,不为空的话就往下走

String webHeader = req.getHeader(Conf.SSO_SESSIONID);
		if (StringUtils.hasLength(webHeader)) {
			chain.doFilter(request, response);
			return;
		}

这个是webFilter的,和Token相反,因为Web端请求头head中永远都是没有数据的,所以要把那个取反去掉,不然这个过滤器永远不会往下走了,这也是一个坑,开始的时候我两边都写了,PC端怎么都不成功,后来debug才发现过滤器卡这里了

过滤器写好了之后,启动用户中心服务端,用户中心客户端,还有你的本地的项目,对了,你本地的项目配置文件里面需要指定用户中心的地址,我本地项目端口是8082,指向的用户中心端口是8080

server:
  port: 8082
  servlet:
    context-path: /
spring:
  freemarker:
    request-context-attribute: request
    suffix: .ftl
hnyfkj.sso.server: http://127.0.0.1:8080/
hnyfkj.sso.logout.path: /logout
hnyfkj.sso.excluded.paths: 
hnyfkj.sso.redis.address: redis://127.0.0.1:6379

本地就两个类,一个启动类Application,一个Config类(注入bean的),其他的暂时没加,根据你的业务来添加Controller

启动之后用PC端来访问下8082,看看出现了什么

在这里插入图片描述直接跳转到了用户中心页面,然后我们登录下看看

在这里插入图片描述又跳转回了我们项目的页面,而且带着ssionId一起返回的,然后我们再直接访问8082,此时因为已经存到了cookie,所以应该是不需要登陆的,我们看下结果

在这里插入图片描述恩,直接登陆了,并没有再次输入账号密码了,这是单系统的单点登录,三八节没事,多系统的我做下再补充,一般用同一个注册中心,相同的账户名,应该在不同的系统都不需要登录的

接下来我们测下手机端,APP端的测试就不可以用网址输入了,因为id在请求头中,我们使用postman进行测试,先输入账号密码进行登录

在这里插入图片描述我们请求成功了,返回了唯一的sessionId,然后我们用这个万能的token去查找接口

在这里插入图片描述把sessionId放进去了请求头,进行请求用户信息,结果返回得到了,用户的信息,恩,这就相当于授权手机之后,手机可以拿着你给的令牌去访问各种链接了

今天就写到这里吧,单点登录可能理解的还不是很透彻,下周还得继续搞用户中心的权限控制,唉,志伟的头发又要掉一撮了,哈哈哈,明天周末有人约没,没人我就又是一个人无聊看Python视频了

发布了12 篇原创文章 · 获赞 1 · 访问量 8151

猜你喜欢

转载自blog.csdn.net/Jaeger_Java/article/details/104701015