电商---单点登录

登录业务介绍(两种模式)

1.1 早期单一服务器,用户认证。

在这里插入图片描述
缺点:单点性能压力,无法扩展

1.2 分布式,SSO(single sign on)模式

在这里插入图片描述
好处 :
用户身份信息独立管理,更好的分布式管理。
可以自己扩展安全策略
跨域不是问题
(跨域:ip,port 不相同! Jsonp={得到其他域的信息}!@CrossOrigin, httpClient )
缺点:
认证服务器访问压力较大。

一、 单点登录业务

在这里插入图片描述

搭建认证中心模块

  1. 修改pom.xml
  2. application.properties
server.port=8087

spring.thymeleaf.cache=false
spring.thymeleaf.mode=LEGACYHTML5

spring.dubbo.application.name=passport-web
spring.dubbo.registry.protocol=zookeeper
spring.dubbo.registry.address=192.168.67.202:2181
spring.dubbo.base-package=com.atguigu.gmall
spring.dubbo.protocol.name=dubbo
spring.dubbo.consumer.timeout=100000
spring.dubbo.consumer.check=false

3.导入静态资源和登录页面
4.建立controller控制器,测试页面

登录功能

在这里插入图片描述

1 思路:
1、	用接收的用户名密码核对后台数据库
2、	将用户信息加载到写入redis,redis中有该用户视为登录状态。
3、	用userId+当前用户登录ip地址+密钥生成token
4、	重定向用户到之前的来源地址,同时把token作为参数附上。
2 实现类核对后台登录信息+用户登录信息载入缓存
public String userKey_prefix="user:";
public String userinfoKey_suffix=":info";
public int userKey_timeOut=60*60*24;

@Override
public UserInfo login(UserInfo userInfo) {
    String password = DigestUtils.md5DigestAsHex(userInfo.getPasswd().getBytes());
        userInfo.setPasswd(password);
        UserInfo info = userInfoMapper.selectOne(userInfo);
        if (info!=null){
            Jedis jedis=null;
            try {
                jedis = redisUtil.getJedis();
                jedis.setex(userKey_prefix+userInfo.getId()+userinfoKey_suffix,userKey_timeOut, JSON.toJSONString(info));
                return info;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (jedis!=null){
                    jedis.close();
                }
            }
        }
    return null;
}

在application.properties 配置文件中要添加
在启动类的时候,不要忘记加,扫描RedisUtils 工具类(@ComponentScan(“com.atguigu.gmall”))

spring.redis.host=192.168.xx.xxx
spring.redis.port=6379
spring.redis.database=0
3 生成token
3.1JWT工具

JWT(Json Web Token)的原理,
一个JWT由三个部分组成:公共部分、私有部分、签名部分。最后由这三者组合进行base64编码得到JWT。

JWT 最重要的作用就是对 token信息的防伪作用

3.2使用配置

pom依赖 放到gmall-web-util中
Jwt工具类
测试下

3.3代码实现

配置nginx / host

    upstream passport.atguigu.com{
       server 192.168.xx.xxx:8087;
    }
   server {
     listen 80;
     server_name passport.atguigu.com;
     location / {
        proxy_pass http://passport.atguigu.com;
        proxy_set_header X-forwarded-for $proxy_add_x_forwarded_for;
     }
    }

控制器


@Value("${token.key}")
String signKey;

@RequestMapping("login")
@ResponseBody
public String login(HttpServletRequest request, UserInfo userInfo){
    // 取得ip地址
    String remoteAddr  = request.getHeader("X-forwarded-for");
    if (userInfo!=null) {
        UserInfo loginUser = userInfoService.login(userInfo);
        if (loginUser == null) {
            return "fail";
        } else {
            // 生成token
            Map map = new HashMap();
            map.put("userId", loginUser.getId());
            map.put("nickName", loginUser.getNickName());
            String token = JwtUtil.encode(signKey, map, remoteAddr);
            return token;
        }
    }
    return "fail";
}
 

4 验证功能

功能:当业务模块某个页面要检查当前用户是否登录时,提交到认证中心,认证中心进行检查校验,返回登录状态、用户Id和用户名称。
在这里插入图片描述

4.1 思路:

1、 利用密钥和IP检验token是否正确,并获得里面的userId

Map<String, Object> map = JwtUtil.decode(token, signKey, currentIp);

2、 用userId检查Redis中是否有用户信息,如果有延长它的过期时间。

 String key=userKey_prefix+userId+userinfoKey_suffix;
 String userJson = jedis.get(key);
 ...
 jedis.expire(key,userKey_timeOut);

3、 登录成功状态返回。

if(userInfo!=null){
                return "success";
}
            return "fail";

二、 业务模块页面登录情况检查

  1. 将登录之后的token 放入cookie 中

  2. 使用拦截器来获取token!{token 中已经有用户的昵称}

  3. 系统中哪些模块需要用户登录 {在需要登录的控制器上添加一个注解} 自定义注解

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值