中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

學(xué)生管理系統(tǒng)seo英文

學(xué)生管理系統(tǒng),seo英文,海鹽網(wǎng)站建設(shè),windows8風(fēng)格網(wǎng)站模板環(huán)境介紹 技術(shù)棧 springbootmybatis-plusmysqljava-jwt 軟件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 1.8 Spring Boot 2.7.13 mybatis-plus 3.5.3.2 Json Web令牌簡稱JWT Token是在服務(wù)端產(chǎn)生的一串字符串是客戶端訪問資源接口(AP)時所需要的資源憑證。…

環(huán)境介紹

技術(shù)棧

springboot+mybatis-plus+mysql+java-jwt

軟件

版本

mysql

8

IDEA

IntelliJ IDEA 2022.2.1

JDK

1.8

Spring Boot

2.7.13

mybatis-plus

3.5.3.2

Json Web令牌簡稱JWT

Token是在服務(wù)端產(chǎn)生的一串字符串是客戶端訪問資源接口(AP)時所需要的資源憑證。

Token認(rèn)證

Token是在服務(wù)端產(chǎn)生的一串字符串是客戶端訪問資源接口(AP)時所需要的資源憑證。

Token認(rèn)證流程

1、客戶端使用用戶名跟密碼請求登錄,服務(wù)端收到請求,驗證用戶名與密碼驗證成功后,服務(wù)端會簽發(fā)一個 token并把這個 token發(fā)送給客戶端,客戶端收到 token后,會把它存儲起來,比如放在cookie里或者localStorage里

2、客戶端每次向服務(wù)端請求資源的時候需要帶著服務(wù)端簽發(fā)的 token

3、服務(wù)端收到請求,然后去驗證客戶端請求里面帶著的 token,如果驗證成功就向客戶端返回請求的數(shù)據(jù)

token用戶認(rèn)證是一種服務(wù)端無狀態(tài)的認(rèn)證方式,服務(wù)端不用存放token數(shù)據(jù)。

用解析 token的計算時間換取 session的存儲空間,從而減服務(wù)器的力,減少頻繁的查詢數(shù)據(jù)庫

token完全由應(yīng)用管理,所以它可以避開同源策略

JWT的使用

JSON Web Token(簡稱JWT)是一個 token的具體實現(xiàn)方式,是目前最流行的跨域認(rèn)證解決方案。JWT的原理是:服務(wù)器認(rèn)證以后,生成一個JSON對象,發(fā)回給用戶。

{

?????? “name” :”張三”,

?????? “time”:”2022年10月10日”

}

用戶與服務(wù)端通信時,都要發(fā)回該JSON對象。服務(wù)器完全只靠這個對象認(rèn)定用戶身份。

為防止用戶篡改數(shù)據(jù),服務(wù)器在生成對象時,會加上簽名

JWT由三個部分組成:Header(頭部)、Payload(負(fù)載)、Signature(簽名)

Header.Payload.Signature

官方描述

Header

JWT頭是一個描述JWT元數(shù)據(jù)的JSON對象,alg屬性表示簽名使用的算法,默認(rèn)為HMAC SHA256(寫為HS256);typ屬性表示令牌的類型,JWT令牌統(tǒng)一寫為JWT。最后,使用Base64 URL算法將上述JSON對象轉(zhuǎn)換為字符串保存

{

? "alg": "HS256",

? "typ": "JWT"

}

Payload

有效載荷部分,是JWT的主體內(nèi)容部分,也是一個JSON對象,包含需要傳遞的數(shù)據(jù)。 JWT指定七個默認(rèn)字段供選擇

iss:發(fā)行人

exp:到期時間

sub:主題

aud:用戶

nbf:在此之前不可用

iat:發(fā)布時間

jti:JWT ID用于標(biāo)識該JWT

Signature

簽名哈希部分是對上面兩部分?jǐn)?shù)據(jù)簽名,需要使用base64編碼后的header和payload數(shù)據(jù),通過指定的算法生成哈希,以確保數(shù)據(jù)不會被篡改。

加入依賴

<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.3.0</version>
</dependency>

數(shù)據(jù)庫

實體類

package com.example.domain;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;/*** * @TableName user*/
@TableName(value ="user")
@Data
public class User implements Serializable {/*** 用戶id*/@TableId(type = IdType.AUTO)private Integer uid;/*** 用戶名*/private String username;/*** 密碼*/private String password;/*** 鹽值*/private String salt;/*** 電話號碼*/private String phone;/*** 電子郵箱*/private String email;/*** 性別:0-女,1-男*/private Integer gender;/*** 頭像*/private String avatar;/*** 是否刪除:0-未刪除,1-已刪除*/private Integer isDelete;/*** 日志-創(chuàng)建人*/private String createdUser;/*** 日志-創(chuàng)建時間*/private Date createdTime;/*** 日志-最后修改執(zhí)行人*/private String modifiedUser;/*** 日志-最后修改時間*/private Date modifiedTime;@TableField(exist = false)private static final long serialVersionUID = 1L;
}

mapper(dao)

package com.example.mapper;import com.example.domain.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.Date;
@Mapper
public interface UserMapper extends BaseMapper<User> {/*** 插入用戶數(shù)據(jù)* @param user 用戶數(shù)據(jù)* @return 受影響的行數(shù)*/int insert(User user);/*** 根據(jù)用戶名查詢用戶是否存在* @param username* @return  成功返回單個用戶數(shù)據(jù),否返回null*/User findByUserName(@Param("username") String username);/*** 根據(jù)uid查詢* @param uid* @return*/User findByUid(@Param("uid") Integer uid);/*** 更新用戶個人資料信息* @param user* @return*/Integer updateUserInfoByUid(User user);/*** 根據(jù)用戶id修改密碼* @param uid* @return password=?,modified_user=?,modified_time=?*/Integer updatePasswordByUid(@Param("uid")Integer uid,@Param("password")String password,@Param("modified_user")String modified_user,@Param("modified_time") Date modified_time);
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper"><resultMap id="UserPojoMap" type="com.example.domain.User"><id column="uid" property="uid"></id><result column="is_delete" property="isDelete"></result><result column="created_user" property="createdUser"></result><result column="created_time" property="createdTime"></result><result column="modified_user" property="modifiedUser"></result><result column="modified_time" property="modifiedTime"></result></resultMap><!--    useGeneratedKeys="true" 開啟主鍵自增 keyProperty="uid" 指定uid字段--><insert id="insert" useGeneratedKeys="true" keyProperty="uid">insert into user(username,password,salt,phone,email,gender,avatar,is_delete,created_user,created_time,modified_user,modified_time)values(#{username},#{password},#{salt},#{phone},#{email},#{gender},#{avatar},#{isDelete},#{createdUser},#{createdTime},#{modifiedUser},#{modifiedTime})</insert><select id="findByUserName" resultMap="UserPojoMap">select * from user where username=#{username}</select><select id="findByUid" resultMap="UserPojoMap">select * from user where uid=#{uid}</select><update id="updatePasswordByUid">update user set password=#{password},modified_user=#{modified_user},modified_time=#{modified_time} where uid=#{uid}</update><update id="updateUserInfoByUid">update user set<if test="phone!=null">phone=#{phone},</if><if test="email!=null">email=#{email},</if><if test="gender!=null">gender=#{gender},</if>modified_user=#{modifiedUser}, modified_time=#{modifiedTime} where uid=#{uid}</update><sql id="Base_Column_List">uid,username,password,salt,phone,email,gender,avatar,is_delete,created_user,created_time,modified_user,modified_time</sql>
</mapper>

service

package com.example.service;import com.example.domain.User;
import com.baomidou.mybatisplus.extension.service.IService;
public interface UserService extends IService<User> {/*** 用戶注冊方法* @param user*/void reg(User user);/*** 用戶登入方法* @param username* @param password* @return*/User login(String username,String password);/*** 根據(jù)uid查詢* @param uid* @return User*//**** @param uid* @param username* @param oldPassword* @param newPassword*/void changePassword(Integer uid,String username,String oldPassword,String newPassword);/*** 通過uid獲取用戶數(shù)據(jù)* @param uid* @return*/User getUserInfoByUid(Integer uid);/*** 修改用戶信息* @param user* @return*/void changeUserInfo(Integer uid,String username,User user);}

ServiceImpl

package com.example.service.impl;import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.domain.User;
import com.example.service.UserService;
import com.example.mapper.UserMapper;
import com.example.service.exception.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;import java.util.Date;
import java.util.UUID;
@Service
@DS("wms")
public class UserServiceImpl extends ServiceImpl<UserMapper, User>implements UserService{@Autowiredprivate UserMapper userDao;@Overridepublic void reg(User user) {//判斷用戶是否被注冊過String username = user.getUsername();User byUserName = userDao.findByUserName(username);if (byUserName == null){//密碼的加密處理:MD5算法//鹽值+password+鹽值String oldPassword =user.getPassword();//獲取鹽值String salt = UUID.randomUUID().toString().toUpperCase();//保存鹽值user.setSalt(salt);String newPassword = getMD5Password(oldPassword,salt);user.setPassword(newPassword);//用戶注冊//        is_delete INT COMMENT '是否刪除:0-未刪除,1-已刪除',//        created_user VARCHAR(20) COMMENT '日志-創(chuàng)建人',//        created_time DATETIME COMMENT '日志-創(chuàng)建時間',//        modified_user VARCHAR(20) COMMENT '日志-最后修改執(zhí)行人',//        modified_time DATETIME COMMENT '日志-最后修改時間',Date nowTime=new Date();user.setIsDelete(0);user.setCreatedUser(user.getUsername());user.setCreatedTime(nowTime);user.setModifiedUser(user.getUsername());user.setModifiedTime(nowTime);Integer rows = userDao.insert(user);if (rows == 0 ){throw  new InsertException("注冊失敗(未知失敗)請重新注冊");};}else {throw new UsernameOccupyException("用戶名被占用");}}@Overridepublic User login(String username,String password) {User UserLogin = userDao.findByUserName(username);//鹽值認(rèn)證String md5Password = getMD5Password(password, UserLogin.getSalt());if (UserLogin == null){throw new UserNullException("用戶不存在");}//檢測密碼是否匹配if (!UserLogin.getPassword().equals(md5Password)){throw new PasswordNotMatchException("用戶密碼錯誤");}//判斷is_delete字段值是否為1表示被標(biāo)記為刪除if (UserLogin.getIsDelete() == 1){throw new UserNullException("用戶已被刪除");}User user = new User();user.setUid(UserLogin.getUid());user.setUsername(UserLogin.getUsername());user.setAvatar(UserLogin.getAvatar());//返回用戶數(shù)據(jù),是為了輔助頁面return user;}@Overridepublic void changePassword(Integer uid, String username, String oldPassword, String newPassword) {User user = userDao.findByUid(uid);if (user ==null){throw new UserNullException("用戶不存在");}if (user.getIsDelete() ==1){throw new UserDeletedException("用戶不存在或已被刪除");}//密碼對比String md5Password = getMD5Password(oldPassword, user.getSalt());if (!user.getPassword().equals(md5Password)){throw new PasswordNotMatchException("原密碼錯誤");}//更新passwordString newPasswordMd5 = getMD5Password(newPassword, user.getSalt());Integer rows = userDao.updatePasswordByUid(uid, newPasswordMd5,username,new Date());if (rows !=1){throw new PasswordUpdateException("修改密碼未知異常");}}//根據(jù)id獲取userInfo@Overridepublic User getUserInfoByUid(Integer uid) {User result = userDao.findByUid(uid);if (result == null || result.getIsDelete() ==1){throw new UserNullException("用戶不存在");}User user = new User();user.setUsername(result.getUsername());user.setUid(result.getUid());user.setPhone(result.getPhone());user.setEmail(result.getEmail());user.setGender(result.getGender());return user;}//修改用戶信息@Overridepublic void changeUserInfo(Integer uid, String username, User user) {User result = userDao.findByUid(uid);if (result == null || result.getIsDelete() ==1){throw new UserNullException("用戶不存在");}user.setUid(uid);user.setModifiedUser(username);user.setModifiedTime(new Date());Integer rows = userDao.updateUserInfoByUid(user);if (rows != 1){throw new InfoUpdateException("修改用戶信息未知異常");}}//password加密方法private String getMD5Password(String password,String salt){for (int i =0;i<5;i++){password = DigestUtils.md5DigestAsHex((salt + password + salt).getBytes()).toUpperCase();}//返回加密之后的密碼return password;}
}

JWT工具類

public class JWTUtil {private static final   String TOKENKey="qgs12345";/*** 生成token* @param map* @return 返回token*/public static String getToken(Map<String,String> map){Calendar instance = Calendar.getInstance();instance.add(Calendar.DATE,7);//7天過期//添加payloadJWTCreator.Builder builder = JWT.create();map.forEach((k,v)->{builder.withClaim(k,v);});builder.withExpiresAt(instance.getTime());//設(shè)置令牌過期時間//生成并返回tokenreturn builder.sign(Algorithm.HMAC256(TOKENKey)).toString();}/*** 驗證token* @param token*/public static void verify(String token){JWT.require(Algorithm.HMAC256(TOKENKey)).build().verify(token);}/*** 獲取token中payload* @param token* @return*/public static DecodedJWT getTokenInfo(String token){return JWT.require(Algorithm.HMAC256(TOKENKey)).build().verify(token);}
}

UserController

@RestController
@RequestMapping("/users")
@CrossOrigin //表示都允許跨域訪問
public class UserController extends BaseController{@Autowiredprivate UserService userModuleService;@RequestMapping("/login")public Map<String,Object> login(String username, String password){Map<String,Object> map =new HashMap<>();try {User data = userModuleService.login(username, password);Map<String,String> payload =new HashMap<>();payload.put("username",data.getUsername());//生成JWT令牌String token =JWTUtil.getToken(payload);map.put("state",true);map.put("msg","登入成功");map.put("token",token);}catch (Exception e){map.put("state",false);map.put("msg","登入失敗");}return map;}}

登錄,產(chǎn)生token

驗證token方式一

認(rèn)證代碼中寫token認(rèn)證流程,過多的認(rèn)證請求會導(dǎo)致代碼冗余

@RestController
@RequestMapping("/users")
@CrossOrigin //表示都允許跨域訪問
public class UserController extends BaseController{@Autowiredprivate UserService userModuleService;@RequestMapping("/login")//驗證token@RequestMapping("/loginVerify")public Map<String,Object> loginVerify(String token){System.out.println(token);Map<String,Object> map =new HashMap<>();try {//生成JWT令牌JWTUtil.verify(token);map.put("state",true);map.put("msg","驗證成功");}catch (Exception e){map.put("state",true);map.put("msg","驗證失敗");}return map;}}

驗證token方式二 JWT攔截器

拋棄方式一的代碼冗余

public class JWTInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {Map<String,Object> map =new HashMap<>();// 獲取請求頭中的JWT令牌String token = request.getHeader("token");// 進(jìn)行JWT令牌的驗證邏輯try {//生成JWT令牌JWTUtil.verify(token);return true;//放行請求}catch (Exception e){map.put("state",false);map.put("msg","token驗證失敗");//map轉(zhuǎn)jsonString msg =new ObjectMapper().writeValueAsString(map);response.setContentType("application/json;charset=utf-8");response.getWriter().println(msg);}return false;}
}

@Component
public class InterceptorConfig implements WebMvcConfigurer {public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new JWTInterceptor()).addPathPatterns("/users//loginVerify")//攔截路徑,根據(jù)實際情況進(jìn)行配置.excludePathPatterns("/users/login","/reg") ;//放行路徑}}

簡化loginVerify后

//驗證token
@RequestMapping("/loginVerify")
public Map<String,Object> loginVerify(HttpServletRequest request){Map<String,Object> map =new HashMap<>();String token =request.getHeader("token");System.out.println(token);map.put("state",true);map.put("msg","驗證成功");return map;
}

請求頭攜帶token效果

http://www.risenshineclean.com/news/38784.html

相關(guān)文章:

  • 合優(yōu)網(wǎng)合川招聘杭州排名優(yōu)化公司電話
  • 網(wǎng)站開發(fā)工程師工作職責(zé)seo模擬點擊軟件
  • 長沙房產(chǎn)交易中心官網(wǎng)丹東網(wǎng)站seo
  • 經(jīng)典網(wǎng)站首頁設(shè)計網(wǎng)絡(luò)營銷評價的名詞解釋
  • 湖北省建設(shè)廳建筑資料官方網(wǎng)站360點睛實效平臺推廣
  • 電子商務(wù)公司營業(yè)執(zhí)照經(jīng)營范圍seo優(yōu)化步驟
  • 遼陽專業(yè)建設(shè)網(wǎng)站公司電話新媒體營銷策略有哪些
  • 做的比較簡約的網(wǎng)站個人開發(fā)app可以上架嗎
  • 石家莊一日游最佳景點天津關(guān)鍵詞優(yōu)化網(wǎng)站
  • 音樂網(wǎng)站建站發(fā)新聞稿平臺
  • 高性能網(wǎng)站建設(shè)進(jìn)階指南:web開發(fā)者性能優(yōu)化最佳實踐重慶網(wǎng)站優(yōu)化軟件
  • 程序源代碼下載網(wǎng)站全球搜索引擎排行榜
  • 做網(wǎng)站注意哪些搜索引擎優(yōu)化的核心是
  • 有什么推薦做簡歷的網(wǎng)站百度官網(wǎng)入口
  • 網(wǎng)站建立企業(yè)巨量千川廣告投放平臺
  • 問題反饋的網(wǎng)站怎么做seo信息查詢
  • 蘇州響應(yīng)式網(wǎng)站建設(shè)進(jìn)入百度
  • 做本地網(wǎng)站賺錢嗎?2020最成功的網(wǎng)絡(luò)營銷
  • 自己做網(wǎng)站出口關(guān)鍵詞優(yōu)化排名平臺
  • 跨境獨立站建站免費手游推廣代理平臺渠道
  • 網(wǎng)站框架指的是什么百度公司推廣電話
  • 吉林省最新疫情最新消息優(yōu)化大師官網(wǎng)登錄入口
  • 滄州 網(wǎng)站建設(shè)鄭州seo外包顧問
  • 學(xué)生靜態(tài)網(wǎng)頁模板成都百度seo公司
  • 做營銷型網(wǎng)站公司蘇州優(yōu)化排名seo
  • muse怎么做響應(yīng)式網(wǎng)站網(wǎng)頁設(shè)計作品集
  • 滕州盛揚(yáng)網(wǎng)絡(luò)公司網(wǎng)站建設(shè)推廣優(yōu)化的含義是什么
  • 南京做網(wǎng)站公司地點南寧seo營銷推廣
  • 做明星粉絲網(wǎng)站seo關(guān)鍵詞排名軟件流量詞
  • 可以做推廣的門戶網(wǎng)站軟件開發(fā)工資一般多少