Login với Facebook trong Spring Boot
NỘI DUNG BÀI VIẾT
Trong bài viết này chúng ta cùng tìm hiểu cách để Login với Facebook trong dự án SpringBoot. Chúng ta sẽ sử dụng đến Spring Social ở bài viết này.
Cài đặt thư viện
Đầu tiên chúng ta thêm những thư viện sau:
- Với Maven chúng ta vào file porm.xml
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-facebook</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
Code language: HTML, XML (xml)
- Với Gradle chúng ta thêm vào file build.gradle
compile group: 'org.springframework.social', name: 'spring-social-facebook', version: '2.0.3.RELEASE'
Code language: JavaScript (javascript)
Cấu hình file SecurityConfig
Chúng ta sẽ cấu hình file SecurityConfig đơn giản như sau:
SecurityConfig.java
@Configuration
@EnableWebSecurity
@ComponentScan(basePackages = { "com.baeldung.security" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll();
}
}
Code language: PHP (php)
Cấu hình file application.properties
Chúng ta thêm đoạn cấu hình để sử dụng Facebook vào trong file application.properties như sau:
spring.social.facebook.appId=YOUR_APP_ID
spring.social.facebook.appSecret=YOUR_APP_SECRET
Trong đó YOUR_APP_ID và YOUR_APP_SECRET các bạn sẽ lấy ở trên trang https://developers.facebook.com mình cũng đã hướng dẫn cách lấy mã tương tự ở bài viết ChatBot các bạn có thể tìm để xem lại.
Thêm cấu hình Facebook vào file SecurityConfig
Tiếp theo chúng ta sẽ thêm các config của Facebook sau vào trong file SecurityConfig
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private FacebookConnectionSignup facebookConnectionSignup;
@Value("${spring.social.facebook.appSecret}")
String appSecret;
@Value("${spring.social.facebook.appId}")
String appId;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login*","/signin/**","/signup/**").permitAll()
...
}
@Bean
public ProviderSignInController providerSignInController() {
ConnectionFactoryLocator connectionFactoryLocator =
connectionFactoryLocator();
UsersConnectionRepository usersConnectionRepository =
getUsersConnectionRepository(connectionFactoryLocator);
((InMemoryUsersConnectionRepository) usersConnectionRepository)
.setConnectionSignUp(facebookConnectionSignup);
return new ProviderSignInController(connectionFactoryLocator,
usersConnectionRepository, new FacebookSignInAdapter());
}
private ConnectionFactoryLocator connectionFactoryLocator() {
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
registry.addConnectionFactory(new FacebookConnectionFactory(appId, appSecret));
return registry;
}
private UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator
connectionFactoryLocator) {
return new InMemoryUsersConnectionRepository(connectionFactoryLocator);
}
}
Code language: PHP (php)
Ở đoạn code trên mình có thêm một số các config mới liên quan facebook:
- Sử dụng ProviderSignInController để kích hoạt xác thực qua Facebook nên nó sẽ cần tới ConnectionFactoryLocator để đăng ký FacebookConnectionFactory với những thuộc tính chúng ta khai báo ở file appilcation.properties ở trên
- Sử dụng SigninAdapter để xử lý nghiệp vụ login cho ứng dụng của chúng ta.
- Sử dụng ConnectionSignUp để xử lý đăng ký tài khoản mới đăng nhập Facebook lần đầu.
Sign-in Adapter
Có thể hiểu đơn giản đây là cầu nối trung gian giúp người dùng có thể sử dụng tài khoản Facebook để đăng nhập ứng dụng của chúng ta
public class FacebookSignInAdapter implements SignInAdapter {
@Override
public String signIn(
String localUserId,
Connection<?> connection,
NativeWebRequest request) {
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(
connection.getDisplayName(), null,
Arrays.asList(new SimpleGrantedAuthority("FACEBOOK_USER"))));
return null;
}
}
Code language: PHP (php)
Connection Sign Up
Khi người dùng đăng nhập với Facebook lần đầu tiên, họ không có tài khoản trong ứng dụng của chúng ta.
Do đó chúng ta cần tạo tài khoản tự động cho họ; chúng ta sẽ sử dụng ConnectionSignUp để tại tài khoản cho những người dùng đó
@Service
public class FacebookConnectionSignup implements ConnectionSignUp {
@Autowired
private UserRepository userRepository;
@Override
public String execute(Connection<?> connection) {
User user = new User();
user.setUsername(connection.getDisplayName());
user.setPassword(randomAlphabetic(8));
userRepository.save(user);
return user.getUsername();
}
}
Code language: PHP (php)
Giao diện
Chúng ta tạo form login như sau ở đây mình sử dụng thymleaf
<html>
<body>
<div th:if="${param.logout}">You have been logged out</div>
<div th:if="${param.error}">There was an error, please try again</div>
<form th:action="@{/login}" method="POST" >
<input type="text" name="username" />
<input type="password" name="password" />
<input type="submit" value="Login" />
</form>
<form action="/signin/facebook" method="POST">
<input type="hidden" name="scope" value="public_profile" />
<input type="submit" value="Login using Facebook"/>
</form>
</body>
</html>
Code language: HTML, XML (xml)
Và trang index.html
<html>
<body>
<nav>
<p sec:authentication="name">Username</p>
<a th:href="@{/logout}">Logout</a>
</nav>
<h1>Welcome, <span sec:authentication="name">Username</span></h1>
<p sec:authentication="authorities">User authorities</p>
</body>
</html>
Code language: HTML, XML (xml)
Trang index sẽ hiển thị username người dùng đang đăng nhập và quyền của họ.
Leave a Reply