项目之单点登录

1. 单点登录

所在位置:
在这里插入图片描述

1.1 单点登录业务介绍

早期单一服务器,用户认证。
在这里插入图片描述缺点:单点性能压力,无法扩展

分布式,SSO(single sign on)模式
在这里插入图片描述
解决 :
用户身份信息独立管理,更好的分布式管理。
可以自己扩展安全策略
跨域不是问题

缺点:
认证服务器访问压力较大。

业务流程图{用户访问业务时,必须登录的流程}{单点登录的过程}
在这里插入图片描述

2. 认证中心模块

2.1 实现思路

1、用接收的用户名密码核对后台数据库
2、核对通过,用uuid生成token
3、将用户id加载到写入redis,redis的key为token,value为用户id。
4、登录成功返回token与用户信息,将token与用户信息记录到cookie里面 重定向用户到之前的来源地址。

数据库表:user_info,并添加一条数据!密码应该是加密的!

2.2 认证中心模块业务代码

实体类:

@Data
@ApiModel(description = "userInfo")
@TableName("user_info")
public class UserInfo extends BaseEntity {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "用户名称")
    @TableField("login_name")
    private String loginName;

    @ApiModelProperty(value = "用户昵称")
    @TableField("nick_name")
    private String nickName;

    @ApiModelProperty(value = "用户密码")
    @TableField("passwd")
    private String passwd;

    @ApiModelProperty(value = "用户姓名")
    @TableField("name")
    private String name;

    @ApiModelProperty(value = "手机号")
    @TableField("phone_num")
    private String phoneNum;

    @ApiModelProperty(value = "邮箱")
    @TableField("email")
    private String email;

    @ApiModelProperty(value = "头像")
    @TableField("head_img")
    private String headImg;

    @ApiModelProperty(value = "用户级别")
    @TableField("user_level")
    private String userLevel;

}

mapper:

public interface UserInfoMapper extends BaseMapper<UserInfo> {
}

接口:

public interface UserService {
    /**
     * 登录方法
     * @param userInfo
     * @return
     */
    UserInfo login(UserInfo userInfo);
}

实现:

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserInfoMapper userInfoMapper;

    @Override
    public UserInfo login(UserInfo userInfo) {
        //注意密码是加密的
        String passwd = userInfo.getPasswd();
        String newPasswd = DigestUtils.md5DigestAsHex(passwd.getBytes());

        //构建构造器查询
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper();
        queryWrapper.eq("login_name", userInfo.getLoginName());
        queryWrapper.eq("passwd", newPasswd);
        UserInfo userInfo1 = userInfoMapper.selectOne(queryWrapper);
        if (userInfo1 != null) {
            return userInfo1;
        }
        return null;
    }
}

控制器:

@RestController
@RequestMapping("/api/user/passport")
public class UserInfoController {
    @Autowired
    UserService userService;
    @Autowired
    RedisTemplate redisTemplate;


    /**
    * @description: 登录
    * @author MIS
    * @date: 2022/10/17 12:05
    * @Param: userInfo
    * @Param: request
    * @Param: response
    * @Return: com.atguigu.gmall.common.result.Result
    */

    @PostMapping("login")
    public Result login(@RequestBody UserInfo userInfo, HttpServletRequest request, HttpServletResponse response) {
        UserInfo info = userService.login(userInfo);
        //密码账号匹配成功
        if (info != null) {
            //用UUid构造token作为存入缓存的key
            String token = UUID.randomUUID().toString().replaceAll("-", "");
            //存储用户信息作为存入缓存的value
            JSONObject userJson = new JSONObject();
            userJson.put("userId", info.getId().toString());
            //同时存入ip作为验证是否同一个ip防止伪造token增加安全性
            userJson.put("ip", IpUtil.getIpAddress(request));
            //存入redis中
            redisTemplate.opsForValue().set(RedisConst.USER_LOGIN_KEY_PREFIX + token, userJson.toJSONString(), RedisConst.USERKEY_TIMEOUT, TimeUnit.SECONDS);
            Object o = redisTemplate.opsForValue().get(RedisConst.USER_LOGIN_KEY_PREFIX + token);
            System.out.println(RedisConst.USER_LOGIN_KEY_PREFIX + token+"==================="+o.toString());
            //返回数据给前端 存入cookie
            HashMap<String, Object> map = new HashMap<>();
            map.put("nickName", info.getNickName());
            map.put("token", token);

            return Result.ok(map);
        } else {
            return Result.fail().message("用户名或密码错误");
        }
    }

    /**
     * 退出登录
     * @param request
     * @return
     */
    @GetMapping("logout")
    public Result logout(HttpServletRequest request){
        //从请求头中获取token, 然后从缓存中删除
      redisTemplate.delete(RedisConst.USER_LOGIN_KEY_PREFIX + request.getHeader("token"));
       return Result.ok();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值