美文网首页
5.用户管理模块

5.用户管理模块

作者: 惜小八 | 来源:发表于2020-05-20 21:28 被阅读0次

该模块主要有十个子模块:注册、登陆、用户名/邮箱验证、获取登陆用户信息、登陆状态重置密码、登陆状态下更新用户信息、忘记密码、提交问题答案、重置密码、退出。

1.MD5代码

用户的密码使用MD5加密后存储在数据库当中

package com.mall.util;

import org.springframework.util.StringUtils;
import java.security.MessageDigest;


public class MD5Util {

    //内部使用的加密算法
    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));
        return resultSb.toString();
    }
    //内部使用的加密算法
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }


    /**
     * 返回大写MD5,origin表示原密码
     */
    private static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname))
                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
            else
                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
        } catch (Exception exception) {
        }
        return resultString.toUpperCase();
    }

    public static String MD5EncodeUtf8(String origin) {
        /**
         * 使用下面的句子来进行加盐,直接返回则表示不加盐MD5
         */
        origin = origin + PropertiesUtil.getProperty("password.salt", "");
        return MD5Encode(origin, "utf-8");
    }


    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

}
**********************PropertiesUtil*****************
package com.mall.util;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;

/**
 * Created by geely
 */
public class PropertiesUtil {

    private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);

    private static Properties props;
    /**
     * PropertiesUtil的实现:要求在Tomcat启动的时候读取到其中的内容
     * 所以此处使用静态块来实现,当该类被Java的类加载器加载的时候,就会首先执行static
     */
    static {
        String fileName = "mall.properties";
        props = new Properties();
        try {
            props.load(new InputStreamReader(PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName),"UTF-8"));
        } catch (IOException e) {
            logger.error("配置文件读取异常",e);
        }
    }

    public static String getProperty(String key){
        String value = props.getProperty(key.trim());
        if(StringUtils.isBlank(value)){
            return null;
        }
        return value.trim();
    }

    public static String getProperty(String key,String defaultValue){

        String value = props.getProperty(key.trim());
        if(StringUtils.isBlank(value)){
            value = defaultValue;
        }
        return value.trim();
    }
}
*************mall.properties***********
password.salt = geelysdafaqj23ou89ZXcj@#$@#$#@KJdjklj;D../dSF.,

2.忘记密码,重置密码时回答问题的答案有效时间

在忘记密码时,一般会有提示问题,通过回答提示问题进行密码的重置,一般在回答问题之后,这个答案在一段时间内时有效的,此处使用google的CacheLoader来存储问题答案的有效时间。

package com.mall.common;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

public class TokenCache {

    //日志打印对象
    private static Logger logger= LoggerFactory.getLogger(TokenCache.class);
    public static final String TOKEN_PREFIX="token_";
    /**
     * maximumSize:当缓存大大小超过10000的时候会采用最少使用算法,将缓存移除,
     * expireAfterAccess:缓存的有效时间是12小时
     * build:缓存的实现,此处使用匿名实现
     */
    private static LoadingCache localCache= CacheBuilder.newBuilder().initialCapacity(1000).maximumSize(1000)
            .expireAfterAccess(12, TimeUnit.HOURS)
            .build(new CacheLoader<String, String>() {
                //缓存默认的数据加载实现,当调用get取之的时候,如果key没有对应的值,就调用这个方法进行加载
                @Override
                public String load(String key) throws Exception {
                    return "null";
                }
            });
    //提供外界的方法
    public static void setKey(String key,String value){
        localCache.put(key,value);
    }
    public static String getKey(String key){
        String value=null;
        try {
            value= (String) localCache.get(key);
            if("null".equals(value)){
                return null;
            }
            return value;
        }catch (Exception e){
            logger.info("cache get error",e);
        }
        return null;
    }
}

3.用户管理模块接口(Controller)

package com.mall.controller.portal;

import com.mall.common.Const;
import com.mall.common.ResponseCode;
import com.mall.common.ServerResponse;
import com.mall.pojo.User;
import com.mall.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/user/")
public class UserController {
    @Autowired
    private IUserService iUserService;

    @RequestMapping(value = "login.do",method = RequestMethod.POST)
    @ResponseBody
    public ServerResponse<User> login(String username, String password, HttpSession session){
        ServerResponse<User> serverResponse=iUserService.login(username, password);
        if(serverResponse.isSuccess()){
            session.setAttribute(Const.CURRENT_USER,serverResponse.getData());
        }
        return serverResponse;
    }

    @ResponseBody
    @RequestMapping(value = "logout.do")
    public ServerResponse logout(HttpSession session){
        session.removeAttribute(Const.CURRENT_USER);
        return ServerResponse.createBySuccess();
    }

    @ResponseBody
    @RequestMapping(value = "register.do",method = RequestMethod.POST)
    public ServerResponse<String> register(User user){
        return iUserService.register(user);
    }

    @ResponseBody
    @RequestMapping(value = "check_valid.do",method = RequestMethod.POST)
    public ServerResponse<String> checkValid(String str,String type){
        return iUserService.checkedValid(str, type);
    }
    //获取登陆用户的信息
    @ResponseBody
    @RequestMapping("get_user_information.do")
    public ServerResponse<User> getUserInformation(HttpSession session){
        User user=(User)session.getAttribute(Const.CURRENT_USER);
        if(user==null){
            return ServerResponse.createByErrorCodeMsg(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getMsg());
        }
        return ServerResponse.createBySuccess(user);
    }
    //更新用户信息,然后存放在session当中
    @ResponseBody
    @RequestMapping("update_user_information.do")
    public ServerResponse<User> updateUserInformation(HttpSession session,User updateUser){
        User user=(User)session.getAttribute(Const.CURRENT_USER);
        if(user==null){
            return ServerResponse.createByErrorCodeMsg(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getMsg());
        }
        updateUser.setId(user.getId());
        updateUser.setUsername(user.getUsername());
        ServerResponse serverResponse=iUserService.updateInformation(updateUser);
        if(serverResponse.isSuccess()){
            session.setAttribute(Const.CURRENT_USER,serverResponse.getData());
        }
        return serverResponse;
    }

    @ResponseBody
    @RequestMapping(value = "rest_password.do",method = RequestMethod.POST)
    public ServerResponse<User> restPassword(HttpSession session,String oldPassword,String newPassword){
        User user=(User)session.getAttribute(Const.CURRENT_USER);
        if(user==null){
            return ServerResponse.createByErrorCodeMsg(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getMsg());
        }
        return iUserService.restPassword(user.getUsername(),oldPassword,newPassword);
    }


    //忘记密码:第一步,获取重置密码问题
    @ResponseBody
    @RequestMapping(value = "forget_get_question.do",method = RequestMethod.POST)
    public ServerResponse<String> forgetGetQuestion(String username){
        return iUserService.forgetGetQuestion(username);
    }
    //忘记密码:第二步,检测问题的答案,返回token
    @ResponseBody
    @RequestMapping(value = "forget_checked_answer.do",method = RequestMethod.POST)
    public ServerResponse<String> forgetCheckedAnswer(String username,String question,String answer){
        return iUserService.forgetCheckedAnswer(username, question, answer);
    }

    //忘记密码:第三步,重置密码
    @ResponseBody
    @RequestMapping("forget_rest_password.do")
    public ServerResponse<String> forgetRestPassword(String username,String password,String token){
        return iUserService.forgetRestPassword(username, password, token);
    }
}

4.用户管理模块接口(service)

package com.mall.service.impl;

import com.mall.common.Const;
import com.mall.common.ServerResponse;
import com.mall.common.TokenCache;
import com.mall.dao.UserMapper;
import com.mall.pojo.User;
import com.mall.service.IUserService;
import com.mall.util.MD5Util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;


@Service("iUserService")
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;
    //校验用户名和密码
    public ServerResponse<User> login(String username, String password){
        int rowCount=userMapper.checkUsername(username);
        if(rowCount==0){
            return ServerResponse.createByErrorMsg("用户不存在");
        }
        //MD5
        password= MD5Util.MD5EncodeUtf8(password);
        User user = userMapper.checkUserPassword(username, password);
        if(user==null){
            return ServerResponse.createByErrorMsg("密码错误");
        }
        user.setPassword(StringUtils.EMPTY);
        return ServerResponse.createBySuccess(user);
    }
    //校验用户名和邮箱,然后查用User到数据库
    public ServerResponse<String>  register(User user){
        ServerResponse validResponse=this.checkedValid(user.getUsername(), Const.USERNAME);
        if(!validResponse.isSuccess()){
            return validResponse;
        }
        validResponse=this.checkedValid(user.getEmail(),Const.EMAIL);
        if(!validResponse.isSuccess()){
            return validResponse;
        }
        user.setRole(Const.Role.ROLE_CUSTOMER);
        //MD5
        user.setPassword(MD5Util.MD5EncodeUtf8(user.getPassword()));
        int rowCount=userMapper.insert(user);
        if(rowCount>0){
            return ServerResponse.createBySuccessMsg("注册成功");
        }
        return ServerResponse.createByErrorMsg("注册失败");
    }
    //检查用户名和邮箱的有效性,校验成功则用户名密码不存在
    public ServerResponse<String> checkedValid(String str,String type){
        if(StringUtils.isBlank(type)){
            return ServerResponse.createByErrorMsg("参数错误");
        }
        if(Const.USERNAME.equals(type)){
            int rowCount=userMapper.checkUsername(str);
            if(rowCount>0){
                return ServerResponse.createByErrorMsg("用户已存在");
            }
        }
        if(Const.EMAIL.equals(type)){
            int rowCount=userMapper.checkEmail(str);
            if(rowCount>0){
                return ServerResponse.createByErrorMsg("邮箱已存在");
            }
        }
        return ServerResponse.createBySuccessMsg("校验成功,用户名、邮箱不存在");
    }
    //检查用户和旧密码,更新新密码
    public ServerResponse<User> restPassword(String username,String oldPassword,String newPassword){
        User user=userMapper.checkUserPassword(username,MD5Util.MD5EncodeUtf8(oldPassword));
        if(user==null){
            return ServerResponse.createBySuccessMsg("旧密码错误");
        }
        user.setPassword(MD5Util.MD5EncodeUtf8(newPassword));
        int rowCount=userMapper.updateByPrimaryKeySelective(user);
        user.setPassword(StringUtils.EMPTY);
        if(rowCount>0){
            return ServerResponse.createBySuccess(user);
        }
        return ServerResponse.createByError();
    }
    //更新用户的个人信息
    public ServerResponse<User> updateInformation(User updateUser){
        int rowCount=userMapper.checkEmailByUserId(updateUser.getEmail(),updateUser.getId());
        if(rowCount>0){
            return ServerResponse.createByErrorMsg("email已存在");
        }
        User endUpdateUser=new User();
        endUpdateUser.setId(updateUser.getId());
        endUpdateUser.setUsername(updateUser.getUsername());
        endUpdateUser.setEmail(updateUser.getEmail());
        endUpdateUser.setQuestion(updateUser.getQuestion());
        endUpdateUser.setAnswer(updateUser.getAnswer());
        rowCount=userMapper.updateByPrimaryKeySelective(endUpdateUser);
        if (rowCount>0){
            return ServerResponse.createBySuccess("更新个人信息成功",endUpdateUser);
        }
        return ServerResponse.createByErrorMsg("更新用户信息失败");
    }
    //使用用户名获取问题,将问题返回给前端
    public ServerResponse<String> forgetGetQuestion(String username){
        ServerResponse validResponse=this.checkedValid(username,Const.USERNAME);
        if(validResponse.isSuccess()){
            return ServerResponse.createByErrorMsg("该用户不存在");
        }
        String question=userMapper.checkQuestionByUsername(username);
        if(StringUtils.isNotBlank(question)){
            return ServerResponse.createBySuccess(question);
        }
        return ServerResponse.createBySuccessMsg("找回密码的问题是空的");
    }
    //检查问题的答案是否正确,设置token并返回给前端
    public ServerResponse<String> forgetCheckedAnswer(String username,String question,String answer){
        int rowCount=userMapper.checkAnswerByUsernameAndQuestion(username,question,answer);
        if(rowCount==0){
            return ServerResponse.createByErrorMsg("问题答案错误");
        }
        //设置token:问题的答案的有效时间
        //key:"token_"+username    value:forgetToken
        String token= UUID.randomUUID().toString();
        TokenCache.setKey(TokenCache.TOKEN_PREFIX+username,token);
        return ServerResponse.createBySuccess("问题答案校验成功",token);
    }

    //检测用户名和token,检测token是否正确,更新密码
    public ServerResponse<String> forgetRestPassword(String username,String password,String token){
        ServerResponse response=this.checkedValid(username,Const.USERNAME);
        if(response.isSuccess()){
            ServerResponse.createByErrorMsg("该用户不存在");
        }
        if(StringUtils.isBlank(token)){
            return ServerResponse.createByErrorMsg("Token无效过着过期");
        }
        if(TokenCache.getKey(TokenCache.TOKEN_PREFIX+username).equals(token)){

            int rowCount=userMapper.updatePasswordByUsername(username,MD5Util.MD5EncodeUtf8(password));
            if(rowCount>0){
                return ServerResponse.createBySuccessMsg("密码重置成功");
            }
            return ServerResponse.createByErrorMsg("密码重置失败");
        }
        return ServerResponse.createByErrorMsg("Token错误,重置密码失败");
    }

    public ServerResponse<String> checkUserRole(User user){
        if(user != null && user.getRole()==Const.Role.ROLE_ADMIN){
            return ServerResponse.createBySuccess("用户是管理员,登陆成功");
        }
        return ServerResponse.createByErrorMsg("用户不是管理员,登陆失败");
    }
}

5.用户管理模块(xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.mall.dao.UserMapper" >
  <resultMap id="BaseResultMap" type="com.mall.pojo.User" >
    <constructor >
      <idArg column="id" jdbcType="INTEGER" javaType="java.lang.Integer" />
      <arg column="username" jdbcType="VARCHAR" javaType="java.lang.String" />
      <arg column="password" jdbcType="VARCHAR" javaType="java.lang.String" />
      <arg column="email" jdbcType="VARCHAR" javaType="java.lang.String" />
      <arg column="phone" jdbcType="VARCHAR" javaType="java.lang.String" />
      <arg column="question" jdbcType="VARCHAR" javaType="java.lang.String" />
      <arg column="answer" jdbcType="VARCHAR" javaType="java.lang.String" />
      <arg column="role" jdbcType="INTEGER" javaType="java.lang.Integer" />
      <arg column="create_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
      <arg column="update_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
    </constructor>
  </resultMap>
  <sql id="Base_Column_List" >
    id, username, password, email, phone, question, answer, role, create_time, update_time
  </sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from mmall_user
    where id = #{id,jdbcType=INTEGER}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
    delete from mmall_user
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="com.mall.pojo.User" >
    insert into mmall_user (id, username, password, 
      email, phone, question, 
      answer, role, create_time, 
      update_time)
    values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
      #{email,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR}, #{question,jdbcType=VARCHAR}, 
      #{answer,jdbcType=VARCHAR}, #{role,jdbcType=INTEGER}, now(),
      now())
  </insert>
  <insert id="insertSelective" parameterType="com.mall.pojo.User" >
    insert into mmall_user
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        id,
      </if>
      <if test="username != null" >
        username,
      </if>
      <if test="password != null" >
        password,
      </if>
      <if test="email != null" >
        email,
      </if>
      <if test="phone != null" >
        phone,
      </if>
      <if test="question != null" >
        question,
      </if>
      <if test="answer != null" >
        answer,
      </if>
      <if test="role != null" >
        role,
      </if>
      <if test="createTime != null" >
        create_time,
      </if>
      <if test="updateTime != null" >
        update_time,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        #{id,jdbcType=INTEGER},
      </if>
      <if test="username != null" >
        #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        #{password,jdbcType=VARCHAR},
      </if>
      <if test="email != null" >
        #{email,jdbcType=VARCHAR},
      </if>
      <if test="phone != null" >
        #{phone,jdbcType=VARCHAR},
      </if>
      <if test="question != null" >
        #{question,jdbcType=VARCHAR},
      </if>
      <if test="answer != null" >
        #{answer,jdbcType=VARCHAR},
      </if>
      <if test="role != null" >
        #{role,jdbcType=INTEGER},
      </if>
      <if test="createTime != null" >
        now(),
      </if>
      <if test="updateTime != null" >
        now(),
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.mall.pojo.User" >
    update mmall_user
    <set >
      <if test="username != null" >
        username = #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        password = #{password,jdbcType=VARCHAR},
      </if>
      <if test="email != null" >
        email = #{email,jdbcType=VARCHAR},
      </if>
      <if test="phone != null" >
        phone = #{phone,jdbcType=VARCHAR},
      </if>
      <if test="question != null" >
        question = #{question,jdbcType=VARCHAR},
      </if>
      <if test="answer != null" >
        answer = #{answer,jdbcType=VARCHAR},
      </if>
      <if test="role != null" >
        role = #{role,jdbcType=INTEGER},
      </if>
      <if test="createTime != null" >
        create_time = #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="updateTime != null" >
        update_time = now(),
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.mall.pojo.User" >
    update mmall_user
    set username = #{username,jdbcType=VARCHAR},
      password = #{password,jdbcType=VARCHAR},
      email = #{email,jdbcType=VARCHAR},
      phone = #{phone,jdbcType=VARCHAR},
      question = #{question,jdbcType=VARCHAR},
      answer = #{answer,jdbcType=VARCHAR},
      role = #{role,jdbcType=INTEGER},
      create_time = #{createTime,jdbcType=TIMESTAMP},
      update_time = now()
    where id = #{id,jdbcType=INTEGER}
  </update>

  <select id="checkUsername" parameterType="string" resultType="int">
    select COUNT(1) from mmall_user where username = #{username}
  </select>
  <select id="checkEmail" parameterType="string" resultType="int">
    select count(1) from mmall_user where email=#{email}
  </select>
  <select id="checkUserPassword" parameterType="map" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from mmall_user
    where username = #{username} and password=#{password}
  </select>

  <select id="checkEmailByUserId" parameterType="map" resultType="int">
    select count(1) from mmall_user where id=#{userId} and email=#{email}
  </select>

  <select id="checkQuestionByUsername" parameterType="string" resultType="string">
    select question from mmall_user where username=#{username}
  </select>

  <select id="checkAnswerByUsernameAndQuestion" parameterType="map" resultType="int">
    select count(1) from mmall_user where username=#{username} and question=#{question} and answer=#{answer}
  </select>

  <update id="updatePasswordByUsername" parameterType="map">
    update mmall_user
    set password=#{password},update_time=now()
    where username=#{username}
  </update>
</mapper>

相关文章

  • 5.用户管理模块

    该模块主要有十个子模块:注册、登陆、用户名/邮箱验证、获取登陆用户信息、登陆状态重置密码、登陆状态下更新用户信息、...

  • 计算机毕业设计SpringBoot+Vue.js学前教育图片智能

    功能 本系统七个部分分别是用户管理模块、用户信息模块、用户留言模块、管理员模块、图片识别模块、学习收藏模块,它们的...

  • Django在线教育网站开发(一)app设计

    经分析,在线教育网站的app主要包括用户管理模块、课程管理模块、机构和教师管理模块和用户操作管理模块四个APP

  • 项目基础框架

    1、用户管理模块 2、用户行为统计模块 3、崩溃捕捉上传模块 4、投诉建议模块 5、网络传输模块:asihttps...

  • IOS工程基础框架

    1、用户管理模块 2、用户行为统计模块 3、崩溃捕捉上传模块 4、投诉建议模块 5、网络传输模块:asihttps...

  • Django+xadmin打造在线考试系统2.0(附代码)

    本期将会介绍用户管理模块和代码开源一些原则。 一、用户管理模块 为了对用户更有效的管理,加入新功能,通过邮箱来实现...

  • 7.Metabase用户管理

    Metabase中只有系统管理员可以对用户管理,用户管理主要包括两个大的模块:用户组的管理和用户管理。其中用户组的...

  • 计算机毕业设计SpringBoot+Vue.js健康管理系统 社

    功能 echarts图、管理员信息模块、用户信息模块、公告信息模块、留言信息模块、血压信息模块、血糖信息模块、糖尿...

  • django-restful(抢杀)

    功能模块分为两大块,分别为简易用户及用户组管理模块以及枪杀模块。 urls设计 / 首页/admin ...

  • Flask-Login 官方文档学习过程记录

    简介 Flask-Login是Flask中用于用户session管理(用户状态管理)的一个模块,它处理用户登录、注...

网友评论

      本文标题:5.用户管理模块

      本文链接:https://www.haomeiwen.com/subject/wewbohtx.html