# JWT ## 前端實現 在需要進行認證的 API 請求前,使用以下程式碼: ```javascript // 先引入 Auth.js <script th:src="@{/Token/auth.js}"></script> // 檢查是否已登入 if (!Auth.isLoggedIn()) { // 如果未登入,重定向到登入頁面 Auth.logout(); } else { // 已登入,準備 API 請求 const ajaxParam = { headers: { 'Authorization': `Bearer ${Auth.getToken()}` }, params: { // 原本要傳送的 RequestBody } }; // 發送 API 請求 axios.get(url, ajaxParam) .then(response => { // 處理響應 }) .catch(error => { // 處理錯誤 if (error.response && error.response.status === 401) { Auth.logout(); // 如果錯誤會移除token並自動定向到登入頁面 } }); } ``` memberProfile.js部分範例 ```javascript! // 獲取會員資料 async function getMemberProfile() { if (!Auth.isLoggedIn()) { Auth.logout(); return; } try { const response = await axios.get('/TickitEasy/api/member/profile', { headers: { 'Authorization': `Bearer ${Auth.getToken()}` } }); console.log('API 回應:', response.data); updateProfileUI(response.data); } catch (error) { console.error('獲取會員資料時發生錯誤:', error); handleApiError(error); } } ``` ## 後端實現 Controller ```java // 先 @Autowired JWTUtil jwtUtil; @PostMapping("/your-endpoint") public ResponseEntity<?> yourMethod( @RequestHeader("Authorization") String authHeader, @RequestBody Map<String, String> requestBody) { try { // 從 Authorization Header 中提取 Token String token = authHeader.replace("Bearer ", ""); // 從 Token 中獲取電子郵件 String email = jwtUtil.getEmailFromToken(token); // 根據電子郵件獲取會員資料 Member member = memberService.findByEmail(email); if (member == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid user"); } // 進行後續操作... return ResponseEntity.ok("操作成功"); } catch (Exception e) { // 處理 Token 無效或過期的情況 return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid or expired token"); } } ``` memberController部分範例 ```java // 處理會員頭貼上傳(需驗證Token) @PostMapping("/profilePic") public ResponseEntity<Map<String, String>> uploadProfilePic( @RequestHeader("Authorization") String authHeader, @RequestParam("profilePic") MultipartFile profilePic) { Map<String, String> response = new HashMap<>(); try { // 從 Authorization Header拿Token String token = authHeader.replace("Bearer ", ""); // 從Token拿電子信箱 String email = jwtUtil.getEmailFromToken(token); // 根據電子信箱拿到會員的資料 Member currentMember = memberService.findByEmail(email); if (currentMember == null) { response.put("error", "會員不存在"); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response); } // 處理頭貼上傳 memberService.uploadProfilePic(currentMember.getMemberID(), profilePic); response.put("message", "頭貼上傳成功"); return ResponseEntity.ok(response); } catch (IOException e) { logger.error("頭貼上傳失敗:{}", e.getMessage()); response.put("error", "頭貼上傳失敗"); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); } catch (Exception e) { logger.error("錯誤:{}", e.getMessage()); response.put("error", "發生錯誤,請稍後再試。"); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); } } ``` ### 補充 **前端:** - 使用 Auth.getToken() 拿到JWT,並在每個API請求的header中包含它``` headers: { 'Authorization': `Bearer ${Auth.getToken()}` },``` - 如果收到401錯誤(未授權),則調用 Auth.logout() 登出。 **後端:** - 每個API都從 Authorization header中拿到JWT。 - 再用 jwtUtil 從token中拿到會員的email。 - 根據email找會員資料。 - 驗證會員不是null後才處理請求。