springboot篇】二十一. 基於springboot電商項目 九 修改密碼,登錄和註銷

中國加油,武漢加油!

篇幅較長,配合目錄觀看

案例準備

  1. 本案例基於springboot篇】二十一. 基於springboot電商項目 八 郵件發送和註冊

1. 修改密碼

1.1 shop-common編寫常量類

package com.wpj.common.constant;

public interface Constants {

    String EMAIL_CODE = "_code";
    String UPPASS_TOKEN ="_token";
    String LOGIN_TOKEN = "login_token";
    String CART_TOKEN="cart_token";
    /**
     * 兩個數據庫
     */
    Integer ORDER_DB_NUM = 2;
    /**
     * 兩個表
     */
    Integer ORDER_TAB_NUM = 2;
}

1.2 shop-sso編寫toInputUsername.html

1.3 Controller編寫方法

@RequestMapping(value = "/inputUsername")
    public String inputUsername(String username, ModelMap map){
        // 先判斷用戶名是否存在
        User user = userService.selectByUsername(username);
        if(user != null){
            String token = UUID.randomUUID().toString(); // 生成token
			redisTemplate.opsForValue().set(username+Constants.UPPASS_TOKEN,token,5,TimeUnit.MINUTES);
            String uppassUrl ="http://localhost:8084/toUpdatePassword?username="+user.getUsername()+"&token="+token;
            String userEmail = user.getEmail();
            Email email = new Email();
            email.setTitle("用戶修改密碼");
            email.setContent("連接:"+uppassUrl);
            email.setTo(user.getEmail());
            rabbitTemplate.convertAndSend("email_exchange","",email);
            String emailTemp = userEmail.replace(userEmail.substring(4, userEmail.indexOf("@")), "*****");
            String toEmail =userEmail.replace(userEmail.substring(0,userEmail.indexOf("@")+1),"email.");
            map.put("msg","修改密碼的連接已經發送您的【"+emailTemp+"】郵箱,請點擊<a href='http://"+toEmail+"'>這裏</a>登陸");

        }else{
            map.put("msg","該【"+username+"】不存在");
        }
        return "inputUsername";
    }

1.4 編寫updatePassword.html

1.5 修改 shop-front的index.html表單的提交方式爲Get

1.6 Controller編寫方法

@RequestMapping(value = "/updatePassword")
@ResponseBody
public ResultEntity updatePassword(String username,String newpass,String token){
    // 判斷token是否有效
    String redisToken = (String)redisTemplate.opsForValue().get(username + Constants.UPPASS_TOKEN);
    if(redisToken != null && redisToken.equals(token)){
        // 根據用戶名查詢對象
        User user = userService.selectByUsername(username);
        if(user != null){
            user.setPassword(newpass); // 替換舊的密碼
            userService.update(user); // 更新密碼
            redisTemplate.delete(username+Constants.UPPASS_TOKEN); // 刪除token
            return ResultEntity.SUCCESS("http://localhost:8084/toLogin");
        }else{
            return ResultEntity.FALL("用戶名不存在");
        }
    }else{
        return ResultEntity.FALL("連接有誤");
    }
}

2. 登錄

2.1 shop-common導包

<dependency>
   <groupId>org.mindrot</groupId>
    <artifactId>jbcrypt</artifactId>
    <version>0.4</version>
</dependency>

2.2 shop-common編寫PasswordUtils

package com.wpj.common.utils;

import org.mindrot.jbcrypt.BCrypt;

public class PasswordUtils {

    /**
     * 密碼加密
     * @param pw 用戶輸入的密碼
     * @return
     */
    public static String hashpw(String pw){
        return BCrypt.hashpw(pw,BCrypt.gensalt());
    }

    /**
     * 密碼的比對
     * @param logPw
     * @param codePw
     * @return
     */
    public static Boolean checkpw(String logPw,String codePw){
        return BCrypt.checkpw(logPw,codePw);
    }
}

2.3 shop-sso導包和

<dependency>
     <groupId>com.google.code.gson</groupId>
     <artifactId>gson</artifactId>
     <version>2.8.5</version>
 </dependency>

2.4 shop-sso的Controller編寫方法

@RequestMapping(value = "/login")
@ResponseBody
public ResultEntity login(String username, String password, String returnUrl,HttpServletResponse resp){
    // 根據用戶名查詢對象
    User user = userService.selectByUsername(username);
    if(user != null){
        // 密碼的比對
        if(PasswordUtils.checkpw(password,user.getPassword())){
            // 把登陸用戶放道redis中
            redisTemplate.opsForValue().set(username,user,5,TimeUnit.DAYS);
            // 把用戶的憑證放道cookie
            Cookie cookie = new Cookie(Constants.LOGIN_TOKEN,username);
            cookie.setMaxAge(60*60*24*5);
            cookie.setHttpOnly(false); // 是否允許js訪問
            cookie.setPath("/"); // 同一個域名下面可以訪問           
            // 寫到cookie
            resp.addCookie(cookie);
            if(StringUtils.isEmpty(returnUrl)){
                returnUrl = "http://localhost:8081/";
            }
            return ResultEntity.SUCCESS(returnUrl);
        }else{
            return ResultEntity.FALL("用戶名或密碼錯誤");
        }

    }else{
        return ResultEntity.FALL("用戶名不存在");
    }
}

@RequestMapping(value = "/isLogin")
@ResponseBody
public String isLogin(String callback, @CookieValue(name = Constants.LOGIN_TOKEN,required =false) String loginToken){
    System.out.println("SSOController.isLogin token:"+loginToken);
    String jsonStr = "";
    if(!StringUtils.isEmpty(loginToken)){
        // 從reids中查詢登錄用戶
        User user= (User) redisTemplate.opsForValue().get(loginToken);
        user.setPassword(""); // 一般要把密碼隱藏了
        jsonStr = new Gson().toJson(user); // 把user對象轉成josn字符串
    }
    // 這樣寫的原因該方法及支持JSONP也支持非JSONP
    return callback == null?jsonStr :callback+"('"+jsonStr +"')"; // info()
}

2.5 編寫login.js

2.6 shop-front的index.html引入login.js

<script type="text/javascript" src="http://localhost:8084/js/login.js"></script>

3. 註銷

3.1 shop-sso的Controller編寫logout方法

@RequestMapping(value = "/logout")
public String logout(@CookieValue(name = Constants.LOGIN_TOKEN,required = false) String loginToken,HttpServletResponse resp){
    // 從redis中刪除登錄的用戶
    redisTemplate.delete(loginToken);
    //刪除cookie中的憑證
    Cookie cookie = new Cookie(Constants.LOGIN_TOKEN,"");
    cookie.setMaxAge(-1); // 關閉瀏覽器就失效
    cookie.setPath("/");
    cookie.setHttpOnly(false);
    resp.addCookie(cookie);
    return "redirect:http://localhost:8084/toLogin";
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章