SSO单点登录项目小结

目录

   什么是单点登录系统?

项目目录:

配置文件相关参数:

哈希环(算法):

 池化思想:

为什么说ThreadLocal适合放用户信息


   什么是单点登录系统?


单点登录的英文名叫做:Single Sign On(简称SSO)。
在以前,一般我们就单系统,所有的功能都在同一个系统上。

后来,我们为了合理利用资源和降低耦合性,于是把单系统拆分成多个子系统。

比如阿里系的淘宝和天猫,很明显地我们可以知道这是两个系统,但是你在使用的时候,登录了天猫,淘宝也会自动登录。

简单来说,单点登录就是在多个系统中,用户只需一次登录,各个系统即可感知该用户已经登录。


项目目录:

 

核心代码:主要是登录,登出,注册,登录校验功能

@RestController
@RequestMapping("/app")
public class AppController {

    @Autowired
    private UserService userService;


    /**
     * Login
     *
     * @param username
     * @param password
     * @return
     */
    @RequestMapping("/login")
    @ResponseBody
    public ReturnT<String> login(String username, String password) {

        // valid login
        ReturnT<UserInfo> result = userService.findUser(username, password);
        if (result.getCode() != ReturnT.SUCCESS_CODE) {
            return new ReturnT<String>(result.getCode(), result.getMsg());
        }

        // 1、make xxl-sso user
        XxlSsoUser xxlUser = new XxlSsoUser();
        xxlUser.setUserid(String.valueOf(result.getData().getId()));
        xxlUser.setUsername(result.getData().getUserName());
        xxlUser.setVersion(UUID.randomUUID().toString().replaceAll("-", ""));
        xxlUser.setExpireMinute(SsoLoginStore.getRedisExpireMinute());
        xxlUser.setExpireFreshTime(System.currentTimeMillis());
        // 2、generate sessionId + storeKey
        String sessionId = SsoSessionIdHelper.makeSessionId(xxlUser);

        // 3、login, store storeKey
        SsoTokenLoginHelper.login(sessionId, xxlUser);

        // 4、return sessionId
        return new ReturnT<String>(sessionId);
    }


    /**
     * Logout
     *
     * @param sessionId
     * @return
     */
    @RequestMapping("/logout")
    @ResponseBody
    public ReturnT<String> logout(String sessionId) {
        // logout, remove storeKey
        SsoTokenLoginHelper.logout(sessionId);
        return ReturnT.SUCCESS;
    }

    /**
     * logincheck
     *
     * @param token
     * @return
     */
    @RequestMapping("/logincheck")
    @ResponseBody
    public ReturnT<XxlSsoUser> logincheck(String token) {

        // logout
        XxlSsoUser xxlUser = SsoTokenLoginHelper.loginCheck(token);
        if (xxlUser == null) {
            return new ReturnT<XxlSsoUser>(ReturnT.FAIL_CODE, "sso not login.");
        }
        return new ReturnT<XxlSsoUser>(xxlUser);
    }

    @RequestMapping("/sign")
    @ResponseBody
    public ReturnT<Boolean> sign(@Validated @RequestBody UserSignParam userSignParam){
            UserInfo userInfo = new UserInfo();
            BeanUtils.copyProperties(userSignParam,userInfo);
            return userService.signUser(userInfo);
    }

}

配置文件相关参数:

  context-path作用:所有接口前都带上/hongyan-sso一级目录

   接口的三级路径:

                第一路径是项目路径 就是这个context-path

                第二路径是模块路径

                第三路径是具体功能

  active: local  表示用local配置文件(如果用test修改为active: test)

server:
  port: 8089
  servlet:
    context-path: /hongyan-sso
spring:
  application:
    name: qcbysso
  profiles:
    active: local
  freemarker:
    templateLoaderPath: classpath:/templates/
    suffix: .ftl
    charset: UTF-8
    request-context-attribute: request
    settings.number_format: 0.##########

哈希环(算法):

哈希环(算法):如果说对数据移量敏感的服务,哈希策略必须选这个;对数据敏感的,不能用取余做哈希

 数据移量敏感:比如数据储存在a机器,下次哈希还得存在a机器,不能存储到别的地方

 /**
     *  方式01: Redis单节点 + Jedis单例 : Redis单节点压力过重, Jedis单例存在并发瓶颈 》》不可用于线上
     *      new Jedis("127.0.0.1", 6379).get("cache_key");
     *  方式02: Redis单节点 + JedisPool单节点连接池 》》 Redis单节点压力过重,负载和容灾比较差
     *      new JedisPool(new JedisPoolConfig(), "127.0.0.1", 6379, 10000).getResource().get("cache_key");
     *  方式03: Redis分片(通过client端集群,一致性哈希方式实现) + Jedis多节点连接池 》》Redis集群,负载和容灾较好, ShardedJedisPool一致性哈希分片,读写均匀,动态扩充
     *      new ShardedJedisPool(new JedisPoolConfig(), new LinkedList<JedisShardInfo>());
     *  方式04: Redis集群;
     *      new JedisCluster(jedisClusterNodes);   
     */

方式01:

这个设计模式的瓶颈:服务端jedis  和单机redis 若任意一个出现问题,服务会终止,

 方式02:

jedis采用集群,将瓶颈归于redis,用于项目简单,不需要高并发,存储的数据不敏感可以用

 方式03和04:

jedis采用哈希  将数据存储到对应的redis上  有点:一致性哈希分片,读写均匀,动态扩充

多采用这种设计模式

 池化思想:

典型的牺牲空间换取时间

例如:数据库连接池,jedis连接池,线程池等等,每次项目启动时先创建一些连接,可以直接用。因为创建连接是需要时间的(如果项目启动创建10条连接,需求只有1条,那么剩余的连接继续使用不回收)


为什么说ThreadLocal适合放用户信息

使用场景,就是用于线程之间上下文传递参数

   从请求开始到返回,都是在一个线程里面执行的,所以我们可以用ThreadLocal适合存放用户信息.这样在这个请求过程中 我们可以在不同位置获取到存储的用户信息.


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值