sso系统使用

一:什么是sso(single sign on) ? 

  sso(单点登录系统)简单说就是客户端第一次访问应用1的时候,由于没有登录,会被引导到登录页面进行登录,如果登录校验通过,将返回一个认证信息ticket,作为认证凭据。下次客户端访问应用2的时候,发送的url请求会携带着ticket作为自己的认证凭据,服务器会将该请求携带的ticket交给认证中心进行比对,检验,如果检验通过,应用2在可以不登录的情况下访问内部的资源信息。

二:单点登录系统的整个登录过程

(1)传统登录方式(单应用下)

图一:为传统的登录方式。在一个工程下这套登录机制是没有问题的。但是集群环境下会出现要求用户多次登录的情况

如何解决集群环境中用户多次登录的情况?

解决多次登录的方案有两种:就是解决session共享的问题

1.配置tomcat集群,在tomcat中配置session共享(session复制),但是问题是tomcat部署的节点过多,会出现性能问题。所以一般不适用这种方式

2.可以使用session服务器,是每个节点保持无状态,保存session信息。模拟session。

单点登录就是为了解决session共享问题提出的一套解决方案。使用redis模拟session,实现session的统一管理。

(2)使用单点登录的业务流程

 登录流程解析:

第一步:第一次访问,进入登录系统输入用户名密码进行验证登录,如果登录成功,生成Token对象,作为认证令牌(token相当于原来的jsessionid字符串,这里使用uuid)  

第二步:将返回的token对象信息存入redis服务器。key 就是token , value就是登录用户的信息

第三步:既然是模拟session,所以也需要设置key的过期时间。

第四步:将token(存储的key)写入cookie中,作为用户请求的url参数信息

第五步:用户第二次访问,首先检查用户是否登录,将写入cookie中的token作为请求参数,服务器会从url中解析token的值,然后将解析的token值作为key查询redis服务器;如果查询结果为空,表示session已经过期,要求客户端跳转到登录页面完成登录操作;如果查询结果不为空,需要将查询的信息(登录用户的信息)作为对象返回,然后重新设置key的过期时间。

第六步:解决跨域的问题,使用js发送ajax请求, 使用jsonp解决跨域问题。需要服务器返回的数据格式为mycallback:{id:xx,name:xx},所以将返回的json数据进行拼接成要求的格式即可。

三:登录过程的核心代码

    @Override
    public E3Result login(String username, String password) {
        try {
            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(!(user.getPassword()).equals(DigestUtils.md5Hex(password.getBytes()))) {
                //校验失败
                return E3Result.build(400, "用户名或者密码错误");
            }

            //登录成功
            //1.创建token对象,使用uuid
            String token = UUID.randomUUID().toString();
            //2.将uuid作为key,用户信息作为value值存入redis中
            jedisClient.set("USER_INFO:"+token, JsonUtils.objectToJson(user));
            //3.设置过期时间,半小时
            jedisClient.expire("USER_INFO:"+token, 1800);
            
            //4.返回登录成功的信息
            
            return E3Result.ok(token);
            
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

解决跨域问题的服务端

    @RequestMapping(value = "/user/token/{token}", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public String getTokenName(@PathVariable String token, String callback) {
        E3Result result = tokenService.getToken(token);
        if (StringUtils.isNotBlank(callback)) {
            // 拼接成页面需要的数据给事
            // mycall({id:1,name:z});
            String json = callback + "(" + JsonUtils.objectToJson(result) + ");";
            System.out.println(json);
            return json;
        }
        return JsonUtils.objectToJson(result);
    }

客户端代码:

var E3MALL = {
    checkLogin : function(){
    //COOKIE_TOKEN_KEY设置的cookie的name值
        var _ticket = $.cookie("COOKIE_TOKEN_KEY");
        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();
});

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C/C++基础

Linux命令(9)——tcpdump命令

tcpdump是一款类Unix/Linux环境下的抓包工具,允许用户截获和显示发送或收到的网络数据包。tcpdump 是一个在BSD许可证下发布的自由软件。

783
来自专栏Linux内核

Linux OOM机制分析

oom_killer(out of memory killer)是Linux内核的一种内存管理机制,在系统可用内存较少的情况下,内核为保证系统还能够继续运行下去...

2597
来自专栏编码小白

ofbiz初级教程

本教程是ofbiz 基本应用,它涵盖了OFBiz应用程序开发过程的基本原理。目标是使开发人员熟悉最佳实践,编码惯例,基本控制流程以及开发人员对OFBiz定制所需...

6593
来自专栏恰同学骚年

Hadoop学习笔记—3.Hadoop RPC机制的使用

  (1)它允许一台计算机程序远程调用另外一台计算机的子程序,而不用去关心底层的网络通信细节,对我们来说是透明的。因此,它经常用于分布式网络通信中。

642
来自专栏北京马哥教育

TcpDump使用手册

0x01 Tcpdump简介 ---- tcpdump 是一个运行在命令行下的嗅探工具。它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他...

4087
来自专栏帅小子的日常

sso系统使用

3928
来自专栏漏斗社区

FineCMS 漏洞不仅皮囊好看,灵魂更有趣

0x00 背景 最近在挖掘FineCMS源码的漏洞,发现了一些有趣的洞,斗哥计划先从配置文件写入开始分析,然后再结合存储XSS进行GetShell,本篇先分析配...

36312
来自专栏犀利豆的技术空间

Redis 命令的执行过程

之前写了一系列文章,已经很深入的探讨了 Redis 的数据结构,数据库的实现,key的过期策略以及 Redis 是怎么处理事件的。所以距离 Redis 的单机实...

611
来自专栏数据和云

【视频】In Memory的内部结构和实现机制

小编寄语 罗马不是一日建成的。新特性5分钟系列视频,带你循序渐进学习Oracle12.2的最新特性,相约成长的路上,不见不散! { 本期话题 } In ...

3096
来自专栏云计算

腾讯云支持 Terraform 开发实践

这篇文章从系统架构开始,到核心库讲解,到实践开发,再到单元测试,比较完整的描述了支持Terraform的开发全过程。

2.4K16

扫码关注云+社区