关于springboot:京淘day18重构京淘项目单点登录

4次阅读

共计 5490 个字符,预计需要花费 14 分钟才能阅读完成。

1. 重构京淘我的项目

1.1 导入 jar 包

 <!-- 引入 dubbo 配置 如果下载失败 则去本地仓库中删除从新下载 -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>

1.2 定义 Dubbo 接口

2. 定义服务生产者

2.1 编辑 UserController

2.2 编辑 YML 配置文件

server:
  port: 8093
  servlet:
    context-path: /
spring:
  datasource:
    #引入 druid 数据源
    #type: com.alibaba.druid.pool.DruidDataSource
    #driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    #链接的是数据库代理
    #url: jdbc:mysql://192.168.126.129:8066/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root

  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp
#mybatis-plush 配置
mybatis-plus:
  type-aliases-package: com.jt.pojo
  mapper-locations: classpath:/mybatis/mappers/*.xml
  configuration:
    map-underscore-to-camel-case: true

logging:
  level: 
    com.jt.mapper: debug

#对于 Dubbo 配置
dubbo:
  scan:
    basePackages: com.jt    #指定 dubbo 的包门路
  application:              #利用名称
    name: provider-user     #一个接口对应一个服务名称 如果是多个实现类则利用名称统一
  registry:
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
  protocol:  #指定协定
    name: dubbo  #应用 dubbo 协定(tcp-ip)  web-controller 间接调用 sso-Service
    port: 20880  #每一个服务都有本人特定的端口 不能反复.` 

3. 定义服务消费者

3.1 编辑 UserController

3.2 编辑 YML 配置文件

server:
  port: 8092    
spring:     #定义 springmvc 视图解析器
  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp

dubbo:
  scan:
    basePackages: com.jt
  application:
    name: consumer-user   #定义消费者名称
  registry:               #注册核心地址
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183` 

4. 实现京淘单点登录业务实现

4.1 用户注册实现

4.1.1 业务需要阐明

阐明: 当用户点击新增按钮时, 应该将数据由 jt-web 服务器, 传递给 jt-sso 我的项目实现入库操作. 同时返回无效信息进行校验.

4.1.2 页面分

1).url 剖析

2). 参数阐明

3). 查看页面 JS

4.1.3 编辑 JT-WEB UserController

 /**
     * 实现用户注册操作
     * 1.url 地址:http://www.jt.com/user/doRegister
     * 2. 参数:   password: admin123
     *           username: admin12332412341234
     *           phone: 13111112227
     * 3. 返回值:  SysResult 对象
     */
    @RequestMapping("/doRegister")
    @ResponseBody   // 将返回值后果转化为 JSON
    public SysResult saveUser(User user){userService.saveUser(user);
        return SysResult.success();} 

4.1.4 编辑 JT-SSO UserService

package com.jt.service;
import com.alibaba.dubbo.config.annotation.Service;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import sun.security.provider.MD5;
@Service
public class DubboUserServiceImpl implements DubboUserService{
    @Autowired
    private UserMapper userMapper;
    /**
     * 业务:
     *  1. 将明码进行加密解决
     *  2. 邮箱临时用电话代替
     * @param user
     */
    @Override
    public void saveUser(User user) {byte[] bytes = user.getPassword().getBytes();
        // 利用 Spring 工具 API 进行加密操作
        String md5Pass = DigestUtils.md5DigestAsHex(bytes);
        user.setPassword(md5Pass).setEmail(user.getPhone());
        userMapper.insert(user);
    }
} 

4.2 用户实现单点登录

4.2.1 业务需要

要求: 用户只须要登录一次, 则能够在任意的服务器享受免密登录. 有效期为 30 天.
sso 介绍:
单点登录 (SingleSignOn,SSO),就是通过用户的一次性甄别登录。当用户在身份认证服务器上登录一次当前,即可取得拜访单点登录零碎中其余关联系统和应用软件的权限,同时这种实现是不须要管理员对用户的登录状态或其余信息进行批改的,这意味着在 多个利用零碎中,用户只需一次登录就能够拜访所有相互信任的利用零碎。这种形式缩小了由登录产生的工夫耗费,辅助了用户治理,是目前比拟风行的 [1]

4.2.2 单点登录实现原理


单点登录实现步骤:
1. 用户通过用户名和明码拜访 jt-web 服务器.
2.JT-WEB 服务器通过 JT-SSO 校验用户名和明码是否正确.
3. 如果用户名和明码正确, 则将数据保留到 redis 中. TICKET 密钥:USERJSON, 之后将密钥返回给用户即可.
4.JT-WEB 服务器将密钥信息保留到用户的 Cookie 中 并且设定 Cookie 的共享 / 无效工夫.

4.2.3 登录页面剖析

1).url 剖析

2). 参数剖析

3). 页面 JS

4.2.4 编辑 UserController

 /**
     * 业务需要:
     *   实现用户单点登录操作
     *   1.url 地址:http://www.jt.com/user/doLogin?r=0.43530970885614617
     *   2. 申请参数:  username: asdasdfas
     *                password: asdfasdfa
     *   3. 返回值后果: SysResult 对象
     *
     * 实现 Cookie 数据存储
     *  1. 获取用户名和明码进行数据校验
     *  2. 获取后端的密钥信息  非空????
     *  3. 如果一切正常, 则将数据存储到 Cookie 中. 门路 / 有效期 / 共享问题
     *
     * 对于 Cookie 阐明:
     *      1.cookie 只能看到本人域名下的 cookie   公有的.
     *      2.setPath 阐明
     *          setPath("/") 个别都是 /  读取 cookie 权限的设定, 根目录中的申请 读取 cookie
     *          setPath("/user") url 地址门路 /user 下时能力获取 cookie 信息.
     *          url1: http://www.jt.com/findUser;
     *          url2: http://www.jt.com/user/findUser;
     *
     */
    @RequestMapping("/doLogin")
    @ResponseBody
    public SysResult userLogin(User user, HttpServletResponse response){String ticket = userService.findUserByUP(user);
        if(!StringUtils.hasLength(ticket)){
            // 如果数据为 null 则示意用户名和明码谬误...
            return SysResult.fail();}

        // 须要将数据保留到 cookie 中
        Cookie cookie = new Cookie("JT_TICKET", ticket);
        cookie.setPath("/");
        cookie.setMaxAge(7*24*60*60); // 设定有效期 7 天无效 单位秒
        cookie.setDomain("jt.com");   // 次要域名中由 jt.com 则能够共享数据
        response.addCookie(cookie);   // 将数据写入客户端
        return SysResult.success();}

4.2.5 编辑 UserService

/**
     * 1. 校验用户名和明码是否正确  不存在间接返回 null
     * 2. 动静生成密钥   将用户信息转化为 JSON
     * 3. 将数据保留到 redis 中 7 天无效.
     * 4. 返回密钥 ticket 信息.
     * @param user
     * @return
     */
    @Override
    public String findUserByUP(User user) {
        String md5Pass =
                DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        user.setPassword(md5Pass);
        //1. 依据对象中不为 null 的属性当做 where 条件
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
        User userDB = userMapper.selectOne(queryWrapper);

        //2. 判断对象是否有值
        if(userDB==null){return null;}

        //3. 示意用户名和明码正确 开启单点登录操作
        String ticket = UUID.randomUUID()
                        .toString().replace("-", "");
        // 转化之前应该将数据进行脱敏解决
        userDB.setPassword("123456");
        String userJSON = ObjectMapperUtil.toJSON(userDB);

        //4. 将数据保留到 redis 中
        jedisCluster.setex(ticket, 7*24*60*60, userJSON);
        return ticket;
    }

4.2.6 成果测试

4.3 用户数据回显

4.3.1 业务剖析

如果用户登录胜利之后, 则通过 cookie 数据利用 JSONP 跨域形式, 实现数据的动静获取.

4.3.2 页面 URL 剖析

1). 页面 URL 剖析

2). 查看页面 JS

4.3.3 编辑 JT_SSO UserController

/**
     * 跨域申请: 实现用户信息获取
     * URL 网址:  http://sso.jt.com/user/query/dca70b16a1c54aea9ebb0b27621250de?callback=jsonp1608021961735&_=1608021961777
     * 参数:    参数 1: ticket 信息    参数 2:callback
     * 返回值:   SysResult 对象(用户数据......)
     */
    @RequestMapping("/query/{ticket}")
    public JSONPObject findUserByTicket(@PathVariable String ticket,
                                        String callback){
        // 如何获取用户信息?  从 redis 中获取数据
        if(jedisCluster.exists(ticket)){String userJSON = jedisCluster.get(ticket);
            SysResult sysResult = SysResult.success(userJSON);
            return new JSONPObject(callback, sysResult);
        }else{return new JSONPObject(callback, SysResult.fail());
        }
    }
正文完
 0