[JAVA] Implement Sign in with Twitter in spring-boot, security, social

What to explain in this article

Since we implemented social login using spring-boot, spring-security, and spring-social, we will explain how to implement it using the sample. I think it will be long, so please select and read only the chapters that you are interested in.

In this sample, you can log in by entering userid / password as well as social login.

Background

I studied spring-boot and spring-security at First Spring Boot. In this book, I use spring-boot and security to create a roster app that allows you to log in and out, but I wanted to add a "Sign in with Twitter" function to it, so I tried to add it, but I had a hard time unexpectedly. Ta ... I decided to write this article in order to eradicate this hardship from the world.

About the sample

Source code

it's here. Https://github.com/PonzyPon/spring-boot-social-demo

Sample what you can do

What you can't do

Sample your DB design

In this sample, we wanted to achieve both unique ID / Password login and social login. Therefore, two tables were created. The ʻUser table, which is the master of the user, and the ʻUserConnection table, which holds the social login information. ʻUser # user_id and ʻUserConnection # userId are the same thing. Use this value to concatenate.

User table

column Mold Supplement
user_id VARCHAR primary key
username VARCHAR This is also UNIQUE.
Entered by the user at login
display_name VARCHAR
encoded_password VARCHAR

UserConnection table

column Mold
userId VARCHAR
providerId VARCHAR
providerUserId VARCHAR
rank INT
displayName VARCHAR
profileUrl VARCHAR
imageUrl VARCHAR
accessToken VARCHAR
secret VARCHAR
refreshToken VARCHAR
expireTime BIGINT

This UserConnection table, but in fact this configuration is almost fixed. I didn't write the source code to operate this table at all, I leave it to spring. [Like this] in spring-framework (https://github.com/spring-projects/spring-social/blob/v1.1.6.RELEASE/spring-social-core/src/main/resources/org/springframework/social A sample of sql is provided in /connect/jdbc/JdbcUsersConnectionRepository.sql). Let's copy and use it.

Source code explanation

What I don't understand while using spring-security and spring-social is ** What is my responsibility? ** That means. In other words, it is difficult to understand the boundary between the part that ** spring does and the part that you should do. ** So I will explain including that side.

Processing flow and its responsible person

User login

Spring does ** not ** for the part that loads User from DB. So there needs to implement an Interface called ʻUserDetailService. Then, the implementation class will be called without permission and spring will load the User. ʻThe source of UserDetailsServiceImpl is here

ユーザーログイン.png

Social login

In the case of social login, it is necessary to confirm the existence of the ʻUserConnectiontable that holds the SNS account information and register the data. However, this is all done by spring. We developers can create a User and load it from the User table. The source ofConnectionSignUpImplis [here](https://github.com/PonzyPon/spring-boot-social-demo/blob/master/src/main/java/com/sample/service/impl/ConnectionSignUpImpl.java) The source ofSocialUserDetailsServiceImpl` is here

ソーシャルログイン.png

Other classes

SignupService and ʻUserContext` are not required

Basically, I am trying to create a sample of social login with the minimum configuration, so there are no unnecessary classes, but for example, SignupService does not have to be created. This Interface was created by myself, and the processing of SignupServiceImpl # createUser may be written in ConnectionSignUpImpl # execute. This time, I just divided the classes because I thought that if the user registration function was added in the future, it would be divided into different classes. Also, ʻUserContext` is a convenient class created so that the userId of the logged-in user can be easily obtained. Social login works without it.

Spring setting is SecurityConfig

I mentioned above that the process of receiving username and password and authenticating is left to spring, but the setting is done with SecurityConfig.

This is the end of the explanation. From here on down, I will explain how to move and play with the sample.

How to move the sample

(If you have the Consumer Key and Consumer Secret of your twitter app, start from 3)

  1. Register the app on twitter (https://apps.twitter.com/) Please enter like this. twitter-app-create.png

  2. After creating the app, set the Consumer Key and Consumer Secret of the twitter app to (..) φ memo. 2018-05-19_22h12_16.png

  3. git clone https://github.com/PonzyPon/spring-boot-social-demo.git

  4. Create application.properties by copying application.properties.sample under src / main / resources

  5. Consumer Key and Consumer Secret on spring.social.twitter.app-id and spring.social.twitter.app-secret in application.properties (..) φ write

  6. Run mvnw spring-boot: run at the root of the project (where pom.xml is) (mvn spring-boot: run is OK for those who have maven installed)

  7. Access localhost: 7000

  8. (*^-^*)

(* If you get an error when logging in to Twitter, first try setting Callback URL Locked of the Twitter app to No. If that doesn't work, you have to google to solve it (^ ○ ^))

How to play with the sample

I want to tweet after logging in with Twitter

I've created a method called HomeController # writeTweetIdIfLoggedInWithTwitter for demo, and if you're logged in on Twitter, you're getting the latest tweetId from the account's timeline and writing it to the console. You can also tweet using the twitter variable used here. It is written in the source as a sample, so please comment it out and try it.

HomeController#writeTweetIdIfLoggedInWithTwitter


// Hello!!Tweet
twitter.timelineOperations().updateStatus("Hello!!");

I want to get the ID of the currently logged in user

ʻCall UserContext # getUserId. The return value is ʻOptional <String> because no one may be logged in. This is the image when using it.

public class Sample {
  @Autowired
  private final UserContext userContext;

  public Data getData() {
    dao.getData(userContext.getUserId().get());
  }
}

in conclusion

I wrote this with the image of an article that would make me happy if I saw it before making this sample. If you have any mistakes, opinions or questions, please do not hesitate to contact us. that's all.

Recommended Posts

Implement Sign in with Twitter in spring-boot, security, social
Implement text link with Springboot + Thymeleaf
Try to implement login function with Spring-Boot
Implement the Like feature in Ajax with Rails.
How to implement UICollectionView in Swift with code only
Implement a simple Rest API with Spring Security with Spring Boot 2.0
Quickly implement a singleton with an enum in Java
Handle passwords hashed with BCryptPasswordEncoder in Spring Security in Perl
Call your own method with PreAuthorize in Spring Security