springboot 学习小记 3:设计用户登录模块,注册新用户

1,登录

2,注册

3,重名校验

4,密码加密

5,session保存登录信息

6,越权校验(只分为用户和管理员两个)

一:

创建common包内创建ApiRestResponce类创建统一Api返回对象

public class ApiRestResponse<T> {//定义泛型,类后面加上<T>,<X>X啥字母都行
    private Integer status;
    private String msg;
    private T data;//泛型

    //定义正常运行时的状态码
    private static final int OK_CODE = 10000;

    private static final String OK_MSG = "SUCCESS";

    //构造函数**************************************

    public ApiRestResponse(Integer status, String msg, T data) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }

    public ApiRestResponse(Integer status, String msg) {
        this.status = status;
        this.msg = msg;
    }
    //默认信息
    public ApiRestResponse() {
    this(OK_CODE,OK_MSG);
    }

    //**************************************************************
    //返回通用的响应对象,成功
    public static <T>  ApiRestResponse<T> success(){
        return new ApiRestResponse<>();
    }

    public static <T>  ApiRestResponse<T> success(T result){
        ApiRestResponse<T> response = new ApiRestResponse<>();
        response.setData(result);
        return response;
    }
    //失败
    public static <T> ApiRestResponse<T> error(Integer code,String msg){
        return new ApiRestResponse<>(code,msg);
    }//创建一个类,将常见的错误收拢在一起,找到枚举值调用,不用自己去写
    public static <T> ApiRestResponse<T> error(DemoExceptionEnum exceptionEnum){
        return new ApiRestResponse<>(exceptionEnum.getCode(),exceptionEnum.getMsg());
    }

    @Override
    public String toString() {
        return "ApiRestResponse{" +
                "status=" + status +
                ", msg='" + msg + '\'' +1111+
                ", data=" + data +
                '}';
    }

    //********************************************************************************************************************
    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

}

由于返回错误信息时有多种异常,每次进行编写又复杂故考虑使用枚举的方法创建异常枚举类

二:

注册功能实现:

创建异常包exception内部添加枚举类(项目名+ExceptionEnum)

/**
 *
 * 描述:   异常枚举
 */
public enum (xxxx)Enum {
    //写枚举时前一个与后一个用","分隔,不能用“;”
    //业务异常
    NEED_USER_NAME(10001,"用户名不能为空"),
    NEED_PASSWORD(10002,"密码不能为空"),
    PASSWORD_TOO_SORT(10003,"密码长度不能少于八位"),
    NOT_USE_THE_SAME_NAME(10004,"不允许重名注册失败"),
    INSERT_FAILED(10005,"插入失败请重试"),
    WRONG_PASSWORD(10007,"密码错误"),
    NAME_NOT_NULL(10006,"名字不能为空"),
    NEED_LOGIN(10008,"需要登录"),
    UPDATE_FAILED(10009, "更新失败"),
    NEED_ADMIN(10010, "无管理员权限"),
    CREATE_FAILED (10011,"创建失败"),
    REQUEST_PARAM_ERROR(10012, "参数错误"),
    //系统异常
    SYSTEM_ERROR(20000,"系统异常");


    /**
     * 异常码
     */
    Integer code;
    /**
     * 异常信息
     */
    String msg;

    DemoExceptionEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

Service中不能直接调用枚举类,故创建统一异常类(项目名+Exception)

/**
 * 统一异常
 */
public class DemoException extends RuntimeException {

    private final Integer code;
    private final String message;

    public DemoException(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public DemoException(DemoExceptionEnum exceptionEnum) {
        this(exceptionEnum.getCode(), exceptionEnum.getMsg());
    }

    public Integer getCode() {
        return code;
    }

    @Override
    public String getMessage() {
        return message;
    }
}

三:controller层

@PostMapping("/register")
@ResponseBody
    public ApiRestResponse register(@RequestParam("userName") String userName, @RequestParam("password") String password){
    //由于参数在请求中加入注解便于识别,加入注解还需指定参数名

//    if (username == null)如果对象不是null,字符串内什么都没有会导致误判
    if (StringUtils.isEmpty(userName)){
        return ApiRestResponse.error(SpringLearnExceptionEnum.NEED_USER_NAME);
    }
    if (StringUtils.isEmpty(password)){
        return ApiRestResponse.error(SpringLearnExceptionEnum.NEED_PASSWORD);
    }
    //密码长度不能少于8位
    if (password.length() < 8){
        return ApiRestResponse.error(SpringLearnExceptionEnum.PASSWORD_TOO_SORT);
    }
    userService.register(userName,password);
    return ApiRestResponse.success();
}

判断用户名密码为空,密码长度,不符合调用枚举类

mapper:新加入一个需要去xml中进行实现

User selectByName(String userName);
<select id="selectByName"  parameterType="java.lang.String" resultMap="BaseResultMap">
  select
  --     <include refid="Base_Column_List"></include>表示将要选取的是一个完整的user对象
  from imooc_mall_user
  where username = #{userName,jdbcType=VARCHAR}
</select>

service:

void register(String userName,String password);
@Override
public void register(String userName, String password) {
    //查询是否存在用户,不允许重名
    User result = userMapper.selectByName(userName);
    if (result != null){
        throw new SpringLearnException(SpringLearnExceptionEnum.NOT_USE_THE_SAME_NAME);
    }

    //写到数据库
    /**
     * 1,创建一个新的User
     * 2,把username传进去
     * 3,password传进去,加盐之后
     * 4,用userMapper 把user对象传进去
     */
    User user = new User();
    user.setUsername(userName);
    try {
        user.setPassword(MD5Utils.getMD5Str(password));
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    int count = userMapper.insertSelective(user);
    if(count == 0){
        throw new SpringLearnException(SpringLearnExceptionEnum.INSERT_FAILED);
    }
}

密码加密用的MD5创建utils包建MD5Utils类

/**
 * 描述  :MD5工具
 */
public class MD5Utils {
    //工具类一般使用static修饰,方便其他类进行调用
    public static String getMD5Str(String strValue) throws NoSuchAlgorithmException {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        return Base64.encodeBase64String(md5.digest((strValue + Constant.SALT).getBytes()));
    }

    public static void main(String[] args) {
        String md5 = null;
        try {
            md5 = getMD5Str("12345678");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        System.out.println(md5);
    }
}

盐值添加方式很多。。。

打开postman进行测试

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
接入第三方登录是让用户方便快捷地使用已有账号登录你的网站或应用程序,提高用户体验的一种方式。本文将介绍如何使用 PHP 实现微信公众号第三方登录。 1. 获取微信授权 首先,需要获取微信用户的授权。具体步骤如下: 1)引导用户打开微信授权页面: ```php $appid = 'your_appid'; $redirect_uri = urlencode('http://yourdomain.com/callback.php'); $scope = 'snsapi_userinfo'; $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=$redirect_uri&response_type=code&scope=$scope&state=STATE#wechat_redirect"; header("Location: $url"); ``` 其中,`$appid` 是你的微信公众号的 AppID,`$redirect_uri` 是授权后回调的 URL,`$scope` 是授权作用域,可以是 `snsapi_base` 或 `snsapi_userinfo`,`$state` 是自定义参数,用于防止 CSRF 攻击。 2)获取授权码: 用户同意授权后,会重定向到 `$redirect_uri` 指定的 URL,带上授权码 `code` 和 `state` 参数。 ```php $code = $_GET['code']; $state = $_GET['state']; ``` 3)获取 access_token 和 openid: 使用授权码 `code` 获取 `access_token` 和 `openid`。 ```php $access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=$appid&secret=$secret&code=$code&grant_type=authorization_code"; $response = file_get_contents($access_token_url); $result = json_decode($response, true); $access_token = $result['access_token']; $openid = $result['openid']; ``` 其中,`$secret` 是你的微信公众号的 AppSecret。 2. 获取用户信息 获取到 `access_token` 和 `openid` 后,可以使用以下代码获取用户信息: ```php $userinfo_url = "https://api.weixin.qq.com/sns/userinfo?access_token=$access_token&openid=$openid&lang=zh_CN"; $response = file_get_contents($userinfo_url); $userinfo = json_decode($response, true); ``` 其中,`$userinfo` 包含用户的昵称、头像等信息。 3. 将用户信息保存到数据库 最后,将获取到的用户信息保存到数据库中,以便下次使用时快速登录。 ```php // 连接数据库 $con = mysqli_connect('localhost', 'username', 'password', 'database'); mysqli_set_charset($con, "utf8"); // 查询用户是否已存在 $sql = "SELECT * FROM users WHERE openid='$openid'"; $result = mysqli_query($con, $sql); if (mysqli_num_rows($result) == 0) { // 用户不存在,插入用户信息 $nickname = mysqli_real_escape_string($con, $userinfo['nickname']); $headimgurl = mysqli_real_escape_string($con, $userinfo['headimgurl']); $sql = "INSERT INTO users (openid, nickname, headimgurl) VALUES ('$openid', '$nickname', '$headimgurl')"; mysqli_query($con, $sql); } // 保存用户登录状态 $_SESSION['openid'] = $openid; ``` 以上就是使用 PHP 实现微信公众号第三方登录的步骤。需要注意的是,为了确保安全性,应该对用户输入的数据进行过滤和验证,防止 SQL 注入和 XSS 攻击等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天海奈奈

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

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

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

打赏作者

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

抵扣说明:

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

余额充值