これはディレクトリです
エンティティークラスの書き込み
前回の記事では、プロジェクトディレクトリと基本フレームワークの構築を完了しました。次に、エンティティクラスの記述を開始します。まず、モデルパッケージの下にpojoサブパッケージを作成します。
注:インターネット上にはPO、VO、POJO、DTOなどの概念に関する情報がすでにたくさんあります。このプロジェクトでは詳細な意味は説明されていません。便宜上、POJOとDTOのみが分けられています。これらのいくつかはあいまいであるか、読者は、間違った除算方法や使い方を許してくれます。
サブパッケージを作成した後、対応するpojoを作成します。テーブルはクラスに対応します。Webプロジェクトを作成した学生がこの手順に精通している場合、著者は対応するクラスを1つずつ作成するプロセスを説明しません。著者を参照してください。 GitHubのGitHubホームページでは、直接インポートされた完全なプロジェクトコードが後でアップロードされます。作成後、必ず3つのアノテーション@ Data、@ AllArgsConstructor、@ NoArgsConstructorを追加してください。
ユーザー認証にトークンを使用する
エンティティークラスの作成後、ユーザー権限認証機能の作成を開始しましたが、このプロジェクトでは、jwtとインターセプターを使用して実装しています。
まず、このプロジェクトには3つの役割しかありません。
- ラボ管理者(ADMIN)
- 研究室メンバー(VIP)
- 一般ユーザー(MEMBER)
この分割方法は厳密で安全ではありません。現在の権限の分割は、通常、ユーザーロールとユーザー権限の2つの部分に分かれています。各ユーザーは特定のロールに対応し、特定のロールは特定の権限を持っています。読者はそれについて考え、より完全にすることができます。権限分割スキーム。
Jwtツールクラスの作成
まず、utilパッケージに移動して、JwtUtilという名前のクラスを作成します。クラスの内容は次のとおりです:
JwtUtil
/**
* @Author Alfalfa99
* @Date 2020/9/13 15:54
* @Version 1.0
* JWT生成以及校验工具类
*/
@ConfigurationProperties("jwt.config")
@Component
public class JwtUtil {
private String key;
private long ttl;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public long getTtl() {
return ttl;
}
public void setTtl(long ttl) {
this.ttl = ttl;
}
/**
* 生成JWT
*
* @param id
* @return
*/
public String createJWT(String id, String roles) {
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
JwtBuilder builder = Jwts.builder().setId(id) //在这里我们将用户的id存入Jwt中,方便后续使用
.setIssuedAt(now)
.signWith(SignatureAlgorithm.HS256, key).claim("roles", roles); //在这里我们将用户的角色存入Jwt中,方便后续鉴权,如果想存别的内容也可以往里写
if (ttl > 0) {
builder.setExpiration(new Date(nowMillis + ttl));
}
return builder.compact();
}
/**
* 解析JWT
*
* @param jwtStr
* @return
*/
public Claims parseJWT(String jwtStr) {
return Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(jwtStr)
.getBody();
}
}
キーはサーバーでの暗号化に使用される暗号文であり、通常はランダムに生成されます。ttlはトークンの有効期限です。トークンの詳細な原則を自分で確認してください。スペースは制限されており、繰り返されません。ここでは、@ConfigurationProperties("jwt.config")
アノテーションを使用してapplication.yml構成ファイルから次の構成を読み取り、フィールドを自動的に挿入します
jwt:
config:
key: SecretKey #服务端加密所使用的密文(自拟)
ttl: 21600000 #毫秒
#请将该段复制至application.yml以便于能够启动项目
トークンに戻ると、トークンは、ログインに成功してユーザーのロールとIDを読み取った後にユーザーによって生成されます。生成されたトークンは、ログインが成功した後にフロントエンドに返され、フロントエンドはインターフェースにアクセスするたびにこのトークンを取得する必要があります。
注:トークンを使用して機密性の高いユーザー情報を保存しないでください。トークンは改ざんを回避するためにのみ使用でき、暗号化はできません。トークン自体が保持するコンテンツは、サーバーの秘密鍵なしで直接解析できます。!!
この時点で、JwtUtilをインスタンス化し、createJWTを使用してトークンを生成するか、parseJWTを使用してトークンを解析できます。
インターセプター(インターセプター)を使用してユーザーアクセスのインターセプトと認証を実現する
上記では、トークンを解析して生成することができましたが、認証認証のために各インターフェースでトークンを再解析すると、面倒になりすぎてサーバーのパフォーマンスが低下します。JavaEEプロジェクトの作成経験がある読者は、フィルターを学習しているはずです。 (フィルター)、インターセプターは、Springフレームワークによって提供されるフィルターに似たコンポーネントですが、インターセプターにはますます強力な機能があり、コードに直接言うことはあまりありません。最初に、メインのスタートアップクラスの同じレベルのディレクトリにインターセプターを作成しますインターセプターパッケージは、インターセプターを格納し、このパッケージの下にTokeninterceptorというクラスを作成するために使用されます。クラスのコンテンツ:
/**
* @Author Alfalfa99
* @Date 2020/9/13 18:18
* @Version 1.0
* 全局校验Token
*/
@Component
public class TokenInterceptor implements HandlerInterceptor {
private final JwtUtil jwtUtil;
public TokenInterceptor(JwtUtil jwtUtil) {
this.jwtUtil = jwtUtil;
}
/**
* 通过拦截器对请求头进行校验
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String header = request.getHeader("Authorization");
if (header != null && !"".equals(header)) {
if (header.startsWith("Bearer ")) {
//获得token
String token = header.substring(7);
//验证token
try {
Claims claims = jwtUtil.parseJWT(token);
String roles = (String) claims.get("roles");
if (roles != null) {
request.setAttribute("uid",claims.getId());
request.setAttribute("roles",roles);
return true;
} else {
throw new BadCredentialsException("令牌已失效");
}
} catch (Exception e) {
throw new BadCredentialsException("令牌已失效");
}
}
}
throw new AuthenticationCredentialsNotFoundException("请先登录");
}
}
トークンは、フロントエンドがキー名を要求するたびに要求ヘッダーに配置する必要がAuthorization
あり、値はBearer Token
(トークンはサーバーによって生成されたトークンです)です。
最初に、@Component
アノテーションを使用してクラスをSpringコンテナーとして登録し、次にクラスを使用してHandlerInterceptor
、ターゲットメソッドが実行される前に処理されるインターフェイスpreHandleを実装します。最初に、後で使用するためにコンストラクターを介してJwtUtilを挿入し、リクエストヘッダーからトークンを読み取ります。トークンが空の場合は、ユーザーがログインしていないことを意味します。例外をスローするだけです。トークンの解析でエラーが発生した場合は、直接エラーをスローします。 OK。この部分の主なアイデアは、トークンのコンテンツを正しく解析できない場合にフロントエンドのエラーメッセージに戻り、フロントエンドがログインページにジャンプして再度ログインできるようにすることです。2つの格納されたユーザーIDとユーザーロールを正しく解析できる場合コンテンツがリクエストフィールドに追加され、ユーザーID uid
とユーザーロールをインターフェースのリクエストから直接読み取ることができますroles
。
このようにして、アクセスするたびにユーザーがログインしたかどうかを判断し、リクエストにユーザーIDとユーザーロールを保存して、その後のコントローラー開発を容易にします。
InterceptorConfigの書き込み
TokenInterceptorクラスの準備が完了すると、トークン認証に関するコンテンツは基本的に終了します。もちろん、InterceptorConfigクラスを記述してインターセプターを構成する必要があります。次に、configパッケージにInterceptorConfigという名前のクラスを作成します。内容は次のとおりです。
/**
* @author 苜蓿
* @date 2020/9/13
* 拦截器配置类
*/
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
private final TokenInterceptor tokenInterceptor;
public InterceptorConfig(TokenInterceptor tokenInterceptor) {
this.tokenInterceptor = tokenInterceptor;
}
@Override
protected void addInterceptors(InterceptorRegistry registry) {
//拦截所有目录,除了通向login和register的接口
registry.addInterceptor(tokenInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/**/login/**", "/**/register/**")
.excludePathPatterns("/**/*.html", "/**/*.js", "/**/*.css");
}
次に、TokenInterceptorは、htmlファイル、cssファイル、jsファイル、ログインおよび登録インターフェースを除くすべてのアクセス要求をインターセプトおよび認証するように構成されています。
これでこのブログの内容は完成です。次のブログでコントローラーの作成を開始します。