JSON Web Token (JWT) là một phương thức xác thực đang được sử dụng rộng rãi trong các ứng dụng web hiện nay. JWT không chỉ thể hiện tính năng xác thực thông thường mà còn cho phép các ứng dụng xác thực và ủy quyền người dùng, kiểm soát quyền truy cập và quản lý phân quyền. Bài viết này sẽ giới thiệu cách xây dựng một ứng dụng xác thực và phân quyền dựa trên JWT với Spring Boot và Angular 8.
1. Mô tả ứng dụng
Chúng ta sẽ xây dựng một ứng dụng quản lý sách, trong đó người dùng có thể đăng nhập để xem danh sách sách và thêm mới sách. Quản trị viên có quyền truy cập vào tất cả các chức năng của ứng dụng, bao gồm quản lý người dùng. Người dùng bình thường chỉ có thể xem danh sách sách và thêm mới sách.
2. Thiết kế cơ sở dữ liệu
Ứng dụng chúng ta sử dụng MySQL để lưu trữ dữ liệu. Chúng ta cần thiết kế các bảng sau:
- user: lưu trữ thông tin người dùng, bao gồm tên đăng nhập, mật khẩu và quyền truy cập (admin hoặc user).
- book: lưu trữ thông tin sách, bao gồm tiêu đề và tác giả.
3. Thiết kế API
Để xác thực và phân quyền, chúng ta cần thiết kế các API sau:
- /login: API để đăng nhập và tạo JWT.
- /books: API trả về danh sách sách dựa trên quyền truy cập của người dùng.
- /books/add: API để thêm mới sách, chỉ có quản trị viên mới có quyền truy cập.
4. Xây dựng phía server với Spring Boot
Đầu tiên, chúng ta cần tạo một model User, bao gồm username, password và role.
```
@Entity
@Table(name="user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String username;
private String password;
private String role;
// get/set methods
...
}
```
Tiếp theo, chúng ta cần tạo một interface UserRepository để truy vấn và cập nhật thông tin người dùng trong cơ sở dữ liệu.
```
@Repository
public interface UserRepository extends JpaRepository
{
User findByUsername(String username);
}
```
Sau đó, chúng ta tạo một service AuthService để xác thực người dùng và tạo JWT.
```
@Service
public class AuthService {
private AuthenticationManager authManager;
private UserRepository userRepo;
private JwtUtil jwtUtil;
@Autowired
public AuthService(AuthenticationManager authManager, UserRepository userRepo, JwtUtil jwtUtil) {
this.authManager = authManager;
this.userRepo = userRepo;
this.jwtUtil = jwtUtil;
}
public String authenticate(String username, String password) {
try {
authManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
final String jwt = jwtUtil.generateToken(userDetails);
return jwt;
} catch (Exception e) {
throw new BadCredentialsException("Invalid username/password");
}
}
}
```
Cuối cùng, chúng ta tạo một controller BookController để xử lý các API ở phía server.
```
@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
@RequestMapping("/api/book")
public class BookController {
@Autowired
private BookService bookService;
@GetMapping("/")
@PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
public ResponseEntity> getAllBooks() {
List books = bookService.getAllBooks();
return ResponseEntity.ok().body(books);
}
@PostMapping("/add")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity> addBook(@RequestBody Book book) {
bookService.addBook(book);
return ResponseEntity.ok().build();
}
}
```
5. Xây dựng phía client với Angular 8
Đầu tiên, chúng ta tạo một service AuthService để gửi thông tin đăng nhập đến phía server và lưu token trả về vào localStorage.
```
@Injectable({
providedIn: 'root'
})
export class AuthService {
private baseUrl = 'http://localhost:8080/api/auth';
constructor(private http: HttpClient) { }
login(credentials: {username: string, password: string }): Observable {
return this.http.post(`${this.baseUrl}/login`, credentials)
.pipe(
tap(res => {
localStorage.setItem('access_token', res.token);
})
);
}
getToken() {
return localStorage.getItem('access_token');
}
}
```
Sau đó, chúng ta tạo một service BookService để lấy thông tin sách từ phía server.
```
@Injectable({
providedIn: 'root'
})
export class BookService {
private baseUrl = 'http://localhost:8080/api/book';
constructor(private http: HttpClient) { }
getAllBooks(): Observable {
return this.http.get(`${this.baseUrl}/`);
}
addBook(book: Book): Observable {
return this.http.post(`${this.baseUrl}/add`, book);
}
}
```
Cuối cùng, chúng ta tạo một component BookComponent để hiển thị danh sách sách và form thêm mới sách.
```
@Component({
selector: 'app-book',
templateUrl: './book.component.html',
styleUrls: ['./book.component.css']
})
export class BookComponent implements OnInit {
title: string;
author: string;
books: Book[];
constructor(private bookService: BookService) { }
ngOnInit() {
this.bookService.getAllBooks().subscribe(books => {
this.books = books;
});
}
addBook() {
let book = new Book();
book.title = this.title;
book.author = this.author;
this.bookService.addBook(book).subscribe(() => {
this.books.push(book);
this.title = '';
this.author = '';
});
}
}
```
6. Kết luận
Trong bài viết này, chúng ta đã tìm hiểu cách sử dụng JWT để xác thực và phân quyền trong ứng dụng web với Spring Boot và Angular 8. Sử dụng JWT giúp tăng cường tính bảo mật và kiểm soát quyền truy cập của người dùng trong ứng dụng.
- Mật khẩu giải nén: tailieuhay.download (nếu có)
- Xem thêm các tài liệu về
LẬP TRÌNH tại ĐÂY
- Xem thêm các tài liệu về
ANGULAR tại ĐÂY