記事ディレクトリ
1. SpringCould+Vue3-Element-Adminログインインターフェース、ユーザー情報インターフェース、トークン検証の実装【Taurus Education Platform】
1.1 背景
このプロジェクトは、興志オンライン総合教育プラットフォームの再構築です。このプロジェクトは名前が変更されました: Taurus Education Platform
キーワード: SpringBoot、SpringCould、Vue3、ユニアプリ
フロントエンド バックグラウンド管理システムには、オープン ソース プロジェクト Vue3-Element-Admin が採用されています。
この記事は主に、SpringCould+Vue3-Element-Admin バックグラウンド管理システムのログイン インターフェイス、ユーザー情報インターフェイス、およびトークン検証の実装を実現することを目的としています。
1.2 データベース
2. ログインインターフェイスとそのトークンの実装
2.1 フロントエンド
フロントエンドはオープンソース プロジェクト Vue3-Element-Admin を使用します。
以下はすべて、Vue3-Element-Admin のコードに対する魔法の変更です。
ログインページは次のとおりです。
元のプロジェクトのリクエスト インターフェイスの戻り値を分析します。
リクエストのペイロード:
フロントエンドリクエストインターフェイスを変更します。
インターフェイス ディレクトリの場所: Src->api->login.js
// 登录接口
export const Login = data => {
return request({
url: 'http://localhost:8001/user/login',
// url: '/api/login',
method: 'post',
data,
})
}
2.2 バックエンド
2.2.1 制御層
バックエンドはフロントエンドから渡された値を受け取ります。
バックグラウンドログイン:
@PostMapping("/user/login")
@ResponseBody //返回给前端一个文本格式
public Message login(@RequestBody BackLoginUser user) {
Message msg=new Message();
System.out.println(user.getUsername());
System.out.println(user.getPassword());
try {
if (StringUtils.isEmpty(user.getUsername())) {
msg.setMessage("登录失败,用户名不能为空");
msg.setStatus(400);
return msg;
}
if (StringUtils.isEmpty(user.getPassword())) {
msg.setMessage("登录失败,密码不能为空");
msg.setStatus(400);
return msg;
}
msg = sysUserService.doLogin(user);
return msg;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
コードの説明:
@RequestBody BackLoginUser ユーザー: フロントエンドからの json 文字列がユーザーに保存されます。
ユーザーにはそれぞれユーザー名とパスワードがあります。
if (StringUtils.isEmpty(user.getUsername())) および if (StringUtils.isEmpty(user.getPassword())) は、ログイン値の 2 つのフィールドが空である場合を除外します。
正常であれば、そのまま下に進みます。
問題がなければ、サービス層に渡されて論理操作(ユーザーが存在するかどうか、アカウントのパスワードが正しいかどうかを問い合わせる)が継続されます。
@Autowired
SysUserService sysUserService;
次のように:
msg = sysUserService.doLogin(user);
return msg;
2.2.2 サービス層
コードは以下のように表示されます:
public Message doLogin(BackLoginUser user) {
User userx = new User();
Message msg=new Message();
userx = sysUserDao.LoginByname(user.getUsername());
System.out.println(userx);
if (userx==null){
msg.setMessage("用户不存在,请注册!");
msg.setStatus(405);
return msg;
}else {
if (user.getUsername().equals(userx.getUsername())
&& user.getPassword().equals(userx.getPassword()) ){
String token = CreateJwt.getoken(userx);
Map<String, String> map = new HashMap<>();
map.put("token",token);
msg.setData(map);
msg.setMessage("登录成功");
msg.setStatus(200);
return msg;
}else {
msg.setMessage("登录失败,密码错误");
msg.setStatus(405);
return msg;
}
}
}
コードの説明:
最初の 2 行には何も言うことはありません。
userx = sysUserDao.LoginByname(user.getUsername()); Dao レイヤーは、データ クエリ操作を実行するために呼び出されます。
最初の if は、ユーザーが存在しない (ユーザー アカウントが正しく入力されていない) という問題を除外することです。
それ以外の場合は、ログイン成功かパスワード間違いに分かれます。
ログインが成功した場合は、トークンを生成する必要があることを意味します。
String token = CreateJwt.getoken(userx);
2.2.3 ツールクラス: CreateJwt
getoken メソッドは、時刻、ユーザー ID、ユーザーのユーザー名、現在時刻、および有効期限に基づいてトークンを生成します。プロセスは次のとおりです。
private static final String key = "0123456789_0123456789_0123456789";
public static String getoken(User user) {
// 设置过期时间,这里设置为1小时
long expirationTime = System.currentTimeMillis() + 3600000;
SecretKey secretKey = new SecretKeySpec(key.getBytes(), SignatureAlgorithm.HS256.getJcaName());
String jwt = Jwts.builder()
.setId(user.getId()+"")
.setSubject(user.getUsername())
.setIssuedAt(new Date())
.setExpiration(new Date(expirationTime)) // 设置过期时间
.signWith(secretKey)
.compact();
return jwt;
}
2.2.4 Daoマッパー
ダオ:
public User LoginByname(String username);
マッパー:
<select id="LoginByname" parameterType="String" resultType="User">
select * from user where username = #{username};
</select>
3. ユーザー情報インターフェースと検証トークン機能の実装
3.1 フロントエンド
ログイン ユーザー情報の取得: リクエストを開始するにはトークンが必要です。バックエンドに送信されると、バックエンドは値を返す前にトークンを検証する必要があります。
import axios from 'axios'
export const GetUserinfo = () => {
const token = localStorage.getItem('VEA-TOKEN');
return axios({
method: 'get',
url: 'http://localhost:8001/api/userinfo',
headers: {
'Authorization': 'Bearer ' + token,
}
});
};
送信後、戻り値を分析します。
ユーザー情報取得用データを変更:data.data
理由:
バックエンドインターフェイスに接続した後、ユーザー情報の表示が実現できません。トラブルシューティングの結果、data の値を取得したい場合は data.data が必要であることがわかりました。
// 获取用户信息
async getUserinfo() {
const {
status, data } = await GetUserinfo()
if (+status === 200) {
this.userinfo = data.data
console.log("myurl:",data.data);
return Promise.resolve(data)
}
},
効果を実感してください:
3.2 バックエンド
3.2.1 制御層
ユーザー情報
@GetMapping("/api/userinfo")
public Message getUserInfo(@RequestHeader("Authorization") String token,
@RequestHeader("User-Agent") String userAgent) {
Message msg=new Message();
try{
String[] parts = token.split("\\s+");
String jwtToken = parts[1];
System.out.println(jwtToken);
String tokenValue = JsonPath.parse(jwtToken).read("$.token");
System.out.println(tokenValue);
msg = sysUserService.userinfo(tokenValue);
return msg;
} catch (Exception e) {
return null;
}
コードの説明
@RequestHeader("Authorization") String token,: フロントエンド パス値のトークンを受け入れます。
try の値は、文字列内のトークン値を取得するためのコードです。
sysUserService.userinfo は、処理のためにトークンをサービスに渡します。
msg = sysUserService.userinfo(tokenValue);
3.2.3 サービス層
コードは以下のように表示されます:
public Message userinfo(String token) {
Message msg=new Message();
Claims claims = CreateJwt.parseToken(token);
User userx = new User();
System.out.println("claims.getId():"+claims.getId());
userx = sysUserDao.LoginById(claims.getId());
System.out.println(userx);
Map<String, String> map = new HashMap<>();
map.put("id", String.valueOf(userx.getId()));
map.put("name",userx.getName());
// role: 0 admin 1 teacher 0 student
String role = "";
if (userx.getRole()==0){
role="admin";
}if (userx.getRole()==1){
role="teacher";
}else {
role="student";
}
map.put("role",role);
map.put("avatar","https://s1.ax1x.com/2023/04/17/p9CjIr6.png");
msg.setData(map);
msg.setMessage("登录成功");
msg.setStatus(200);
return msg;
}
userinfo は主にトークンの解析と戻り値を実現します。
書いてみてわかったのですが、この部分はまだ終わっていないので、トークン解析の結果を判断して、間違っていたらステータスコード500を返さなければなりません。
役割は単純な判断割り当てです: 役割: 0 管理者 1 教師 0 生徒
HashMap を使用して必要なデータ値を直接プッシュし、最後にそれらを Data に入れてバックエンドに渡します。
3.2.3 ツールクラス: CreateJwt
public static Claims parseToken(String token) {
System.out.println(token);
try {
SecretKey secretKey = new SecretKeySpec(key.getBytes(), SignatureAlgorithm.HS256.getJcaName());
Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
return claims;
} catch (ExpiredJwtException e) {
// Token已过期
System.out.println("Token已过期");
} catch (JwtException e) {
// Token解析失败
System.out.println("Token解析失败");
}
return null;
}
このコードは Chatgpt を使用して私が生成したものです。もちろん、私のデバッグが少し含まれています。Chatgpt はかなりよく書かれています。
このブロックは主にトークンを解析するためのものです。
3.2.4 Daoマッパー
ダオ:
User LoginById(String id);
マッパー:
<select id="LoginById" parameterType="String" resultType="User">
select * from user where id = #{id};
</select>