微服务之用户注册与登录

用户注册逻辑:用户注册账号,输入姓名邮箱等信息注册后,后端就会发送邮件给用户邮箱。邮箱收到一个url,这个url信息中包含了用户名和uuid,点击后,也就是访问了激活的后端代码,后端将user表中的is_verfiy字段改成Y,完成验证 。
登陆的时候仅允许注册并激活的用户登陆。

注册时获取图片验证码的代码
CaptchaController:

package com.cskaoyan.gateway.controller.user;

/**
 * create by ciggar on 2020/04/05
 */

import com.mall.commons.result.ResponseData;
import com.mall.commons.result.ResponseUtil;
import com.mall.commons.tool.utils.CookieUtil;
import com.mall.user.IKaptchaService;
import com.mall.user.annotation.Anoymous;
import com.mall.user.constants.SysRetCodeConstants;
import com.mall.user.dto.KaptchaCodeRequest;
import com.mall.user.dto.KaptchaCodeResponse;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("/user")
public class CaptchaController {

    @Reference(timeout = 3000, check = false)
    IKaptchaService kaptchaService;

    /**
     * 获取验证码
     */
    @Anoymous
    @GetMapping("/kaptcha")
    public ResponseData getKaptchaCode(HttpServletResponse response) {
        KaptchaCodeRequest kaptchaCodeRequest = new KaptchaCodeRequest();
        // 获取图片验证码
        KaptchaCodeResponse kaptchaCodeResponse = kaptchaService.getKaptchaCode(kaptchaCodeRequest);
        if (kaptchaCodeResponse.getCode().equals(SysRetCodeConstants.SUCCESS.getCode())) {
            // 生成一个cookie  key:kaptcha_uuid,value:uuid
            Cookie cookie = CookieUtil.genCookie("kaptcha_uuid", kaptchaCodeResponse.getUuid(), "/", 60);
            cookie.setHttpOnly(true);
            response.addCookie(cookie);
            return new ResponseUtil<>().setData(kaptchaCodeResponse.getImageCode());
        }
        return new ResponseUtil<>().setErrorMsg(kaptchaCodeResponse.getCode());
    }

    @Anoymous
    @PostMapping("/kaptcha")
    public ResponseData validKaptchaCode(@RequestBody String code, HttpServletRequest httpServletRequest) {
        KaptchaCodeRequest request = new KaptchaCodeRequest();
        String uuid = CookieUtil.getCookieValue(httpServletRequest, "kaptcha_uuid");
        request.setUuid(uuid);
        request.setCode(code);
        //  校验验证码
        // 通过uuid去获取验证码,和我们传过去的验证码对比,如果一致,验证成功,否则验证失败。
        KaptchaCodeResponse response = kaptchaService.validateKaptchaCode(request);
        if (response.getCode().equals(SysRetCodeConstants.SUCCESS.getCode())) {
            return new ResponseUtil<>().setData(null);
        }
        return new ResponseUtil<>().setErrorMsg(response.getCode());
    }
}

KaptchaServiceImpl:

package com.mall.user.services;

import com.mall.user.IKaptchaService;
import com.mall.user.constants.SysRetCodeConstants;
import com.mall.user.dal.entitys.ImageResult;
import com.mall.user.dto.KaptchaCodeRequest;
import com.mall.user.dto.KaptchaCodeResponse;
import com.mall.user.utils.ExceptionProcessorUtils;
import com.mall.user.utils.VerifyCodeUtils;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * ciggar
 * create-date: 2019/8/6-14:45
 */
@Slf4j
@Component
@Service
public class KaptchaServiceImpl implements IKaptchaService {

    @Autowired
    RedissonClient redissonClient;

    private final String KAPTCHA_UUID = "kaptcha_uuid";


    @Override
    public KaptchaCodeResponse getKaptchaCode(KaptchaCodeRequest request) {
        KaptchaCodeResponse response = new KaptchaCodeResponse();
        try {
            // 生成带验证码的图片,调用的一些Java和图形相关的API
            ImageResult capText = VerifyCodeUtils.VerifyCode(140, 43, 4);
            String uuid = UUID.randomUUID().toString();
            // 把k-v放入redis中,k:KAPTCHA_UUID+uuid,v:capText.getCode()
            RBucket rBucket = redissonClient.getBucket(KAPTCHA_UUID + uuid);
            rBucket.set(capText.getCode());
            log.info("产生的验证码:{},uuid:{}", capText.getCode(), uuid);
            // 设置过期时间
            rBucket.expire(120, TimeUnit.SECONDS);
            // 把验证码图片对象返回
            response.setImageCode(capText.getImg());
            response.setUuid(uuid);
            response.setCode(SysRetCodeConstants.SUCCESS.getCode());
            response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("KaptchaServiceImpl.getKaptchaCode occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public KaptchaCodeResponse validateKaptchaCode(KaptchaCodeRequest request) {
        KaptchaCodeResponse response = new KaptchaCodeResponse();
        try {
            request.requestCheck();
            String redisKey = KAPTCHA_UUID + request.getUuid();
            RBucket<String> rBucket = redissonClient.getBucket(redisKey);
            String code = rBucket.get();
            log.info("请求的redisKey={},请求的code={},从redis获得的code={}", redisKey, request.getCode(), code);
            if (StringUtils.isNotBlank(code) && request.getCode().equalsIgnoreCase(code)) {
                response.setCode(SysRetCodeConstants.SUCCESS.getCode());
                response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
                return response;
            }
            response.setCode(SysRetCodeConstants.KAPTCHA_CODE_ERROR.getCode());
            response.setMsg(SysRetCodeConstants.KAPTCHA_CODE_ERROR.getMessage());
        } catch (Exception e) {
            log.error("KaptchaServiceImpl.validateKaptchaCode occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }
}

  • 对称加密:

A给B传输数据m,在传输的过程中+e(加密),B收到了数据c后,-e(解密),获得数据m。
加密操作可能更复杂,如m*e+s。

  • 非对称加密:

A把传输数据给B,B首先生成两个具有相关新的数字e(公钥)和d(私钥)。
B把e传给A(以公开的方式), A通过e公钥的某个算法(例如+e)得到一个c(密文),并把c传给B(以公开的方式)。
A收到密文c后,通过密文求解原文的过程不是-e,而是-d(私钥),解得m(明文)。
也就是说加密时用e(公钥)进行加密,解密时用d(私钥)进行解密。

就算你知道e(公钥)和c(密文),你也不知道私钥,无法解密而获得m(明文)。

  • 下面来介绍一种最典型的非对称加密方式:RSA加密算法
  1. 要求B找出两个质数p、q。
  2. n = p * q
  3. f(n) = (p - 1) * (q - 1) (欧拉函数)
  4. 找出公钥e,1 < e < f(n) 且 e和f(n)互斥,在这个条件内随便找一个整数即可。
    找出私钥d,使得e*d/f(n)后的余数为1。

传输的数据是m
加密:m^e / n 求余数c
解密:c^d / n 求余数m(可以证明这个余数一定是m)。

这种算法的安全性如何呢?
传输中可能被截取的数据有:n、e、c
解密需要的数据:n、d、c
黑客要想解密就得根据e求出d,已知公式:e*d/f(n)后的余数为1。所以得知道f(n),要知道f(n)就得先知道p、q,要知道p、q就得对n进行质因数分解。
大数的质因数分解是很困难的。
RSA算法常用的n是1024位的二进制数,目前想分解这么大的数,普通计算机需要计算十年,量子计算机需要计算七天,所以银行系统都会定期进行更新。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要使用Spring Cloud搭建微服务登录,你可以按照以下步骤进行操作: 1. 创建认证服务:首先,你需要创建一个认证服务,用于处理用户的登录和身份验证。你可以使用Spring Security来实现用户认证和授权功能。在认证服务,你可以定义用户账号、密码以及角色等信息。 2. 配置认证服务:在认证服务,你需要配置Spring Security来定义登录接口、认证规则和权限控制等。可以使用基于用户名密码的登录方式,也可以使用其他方式,如OAuth2.0等。确保你的认证服务能够正确验证用户的身份,并返回相应的访问令牌。 3. 创建其他微服务:除了认证服务外,你还需要创建其他的微服务,用于提供不同的业务功能。这些微服务可以是独立的应用程序,通过Spring Cloud注册到服务注册心,并与认证服务进行通信。 4. 集成认证服务:在其他微服务,你需要集成认证服务,以便验证用户的访问权限。可以通过在请求头携带访问令牌,并在微服务进行校验来实现。使用Spring Security OAuth2或者JWT等技术来实现令牌的生成与验证。 5. 配置路由和网关:为了统一管理和保护微服务,你可以使用Spring Cloud Gateway或Zuul等网关技术来配置路由和访问控制规则。通过网关,你可以对外暴露统一的登录接口,并在用户登录成功后将请求转发到相应的微服务。 6. 前端集成:最后,你需要在前端应用集成登录功能。前端应用可以使用Spring Boot、React、Angular或Vue等框架进行开发。通过调用登录接口获取访问令牌,并在后续的请求携带令牌进行访问控制。 总结来说,使用Spring Cloud搭建微服务登录需要创建认证服务、配置认证规则和权限控制、集成认证服务到其他微服务、配置路由和网关以及前端集成等步骤。这样可以实现用户的登录和访问权限控制。希望以上信息对你有所帮助!如果有任何问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-玫瑰少年-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值