The goal of this project is to implement an application called movie-app
to manage movies. For it, we will implement a back-end application called movie-api
using Spring Boot
and a font-end application called movie-ui
using ReactJS. Besides, we will use OAuth2
(Social Login) to secure both applications.
-
Spring Boot
Web Java backend application that exposes a Rest API to create, retrieve and delete movies. If a user hasADMIN
role he/she can also retrieve information of other users or delete them. The application secured endpoints can just be accessed if a valid JWT access token is provided.In order to get the JWT access token, the user can login using the credentials (
username
andpassword
) created when he/she signed up directly to the application.movie-api
stores its data inMySQL
database.movie-api
has the following endpointsEndpoint Secured Roles POST /auth/authenticate -d {"username","password"}
No POST /auth/signup -d {"username","password","name","email"}
No GET /public/numberOfUsers
No GET /public/numberOfMovies
No GET /api/users/me
Yes ADMIN
,USER
GET /api/users
Yes ADMIN
GET /api/users/{username}
Yes ADMIN
DELETE /api/users/{username}
Yes ADMIN
GET /api/movies [?text]
Yes ADMIN
,USER
POST /api/movies -d {"imdb","description"}
Yes ADMIN
DELETE /api/movies/{imdb}
Yes ADMIN
-
ReactJS
frontend application where a user with roleUSER
can retrieve the information about movies. On the other hand, a user with roleADMIN
has access to all secured endpoints, including endpoints to create and delete movies.In order to access the application, a
user
oradmin
can login using his/herGithub
account or using the credentials (username
andpassword
) created when he/she signed up directly to the application. All the requests coming frommovie-ui
to secured endpoints inmovie-api
have the JWT access token. This token is generated when theuser
oradmin
logins.movie-ui
usesSemantic UI React
as CSS-styled framework.
-
Github
In this link, it's explained how to create a Github App
Note: Other providers like
To explain how it works, we will use Github
as OAuth2 provider example. However, this flow is similar to other providers. All the OAuth2 provider configuration is done in the application.yml. The oauth2Login
configuration is done in WebSecurityConfig
-
The Social Login with
Github
starts bymovie-app
client redirecting the user to the following URLhttp://localhost:8080/oauth2/authorization/github
-
The OAuth2 provider will receive the request similar to
https://github.com/login/oauth/authorize?response_type=code&client_id=<CLIENT_ID>&scope=read:user&state=<STATE>&redirect_uri=http://localhost:8080/login/oauth2/code/github
-
The user is redirected to the OAuth2 provider login form
https://github.com/login?client_id=<CLIENT_ID>&return_to=/login/oauth/authorize?client_id=<CLIENT_ID>&redirect_uri=http://localhost:8080/login/oauth2/code/github&response_type=code&scope=read:use&state=<STATE>
-
User provide his/her credentials
-
User allows or denies the permissions to
movie-app
-
If user denies permissions, the OAuth2 provider will redirect the user to the callback URL registered when creating the
movie-app
with an error.The component that handles it is the
Spring Boot
defaultSimpleUrlAuthenticationFailureHandler
. It can be customized if needed. -
If user allows permissions, the OAuth2 provider will redirect the user to the callback URL registered when creating the
movie-app
with theauthorization_code
The redirect URL will be similar to
http://localhost:8080/login/oauth2/code/github?code=<CODE>&state=<STATE>
Once received the redirect, Spring Security will exchange the
authorization_code
for anaccess_token
and callCustomOAuth2UserService
that will check (byusername
) whether the user is present or not in themovie-app
database. If it is not present, a new entry for the user is created; otherwise, a few user information (likeimageUrl
andemail
) is updated.In the end, the component
CustomAuthenticationSuccessHandler
, extendsSimpleUrlAuthenticationSuccessHandler
, is invoked. It's responsible for creating a JWT access token and sending it to the user in theredirect_uri
. We are using asredirect_uri
a url present inmovie-ui
,http://localhost:3000/oauth2/redirect
. The JWT token informed in theredirect_uri
as a query string, like it's shown belowhttp://localhost:3000/oauth2/redirect?token=eyJ0eXAiOiJKV1QiLCJhbGc...xaY0KWdqG2JDDk-iIrgIPDZvcA7Q
-
-
Open a terminal and inside
springboot-react-social-login
root folder rundocker-compose up -d
-
Wait for
mysql
Docker container to be up and running. To check it, rundocker-compose ps
-
movie-api
-
Open a terminal and navigate to
springboot-react-social-login/movie-api
folder -
Export the following environment variables for the
Client ID
andClient Secret
of the Social Apps (see how to get them in Creating OAuth2 apps for Social Login)export GITHUB_CLIENT_ID=... export GITHUB_CLIENT_SECRET=...
-
Run the following
Maven
command to start the application./mvnw clean spring-boot:run
-
-
movie-ui
-
Open another terminal and navigate to
springboot-react-social-login/movie-ui
folder -
Run the command below if you are running the application for the first time
npm install
-
Run the
npm
command below to start the applicationnpm start
-
Application | URL | Credentials |
---|---|---|
movie-api | http://localhost:8080/swagger-ui.html | |
movie-ui | http://localhost:3000 | admin/admin , user/user or signing up a new user |
-
The gif below shows a
user
loging in using theGithub
-
The gif below shows an
admin
loging in using his application account
-
Manual Test
-
Access
movie-ui
at http://localhost:3000 -
Click
Login
and then, connect withGithub
-
Provide your
Github
credentials
-
-
Automatic Endpoints Test
-
Open a terminal and make sure you are in
springboot-react-social-login
root folder -
Run the following script
./movie-api/test-endpoints.sh
It should return something like the output below, where it shows the http code for different requests
POST auth/authenticate ====================== admin access token ------------------ eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJleHAiOjE1ODY2MjM1MjksImlhdCI6MTU4Nj..._ha2pM4LSSG3_d4exgA user access token ----------------- eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJleHAiOjE1ODY2MjM1MjksImlhdCIyOSwian...Y3z9uwhuW_nwaGX3cc5A POST auth/signup ================ user2 access token ------------------ eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJleHAiOjE1ODY2MjM1MjksImanRpIjoiYTMw...KvhQbsMGAlFov1Q480qg Authorization ============= Endpoints | without token | user token | admin token | ------------------------- + ------------- + ----------- + ------------ | GET public/numberOfUsers | 200 | 200 | 200 | GET public/numberOfMovies | 200 | 200 | 200 | ......................... + ............. + ........... + ............ | GET /api/users/me | 401 | 200 | 200 | GET /api/users | 401 | 403 | 200 | GET /api/users/user2 | 401 | 403 | 200 | DELETE /api/users/user2 | 401 | 403 | 200 | ......................... + ............. + ........... + ............ | GET /api/movies | 401 | 200 | 200 | POST /api/movies | 401 | 403 | 201 | DELETE /api/movies/abc | 401 | 403 | 200 | ------------------------------------------------------------------------ [200] Success - [201] Created - [401] Unauthorized - [403] Forbidden
-
- MySQL
docker exec -it mysql mysql -uroot -psecret --database=moviedb show tables;
-
To stop
movie-api
andmovie-ui
, go to the terminals where they are running and pressCtrl+C
-
To stop and remove docker-compose containers, network and volumes, go to a terminal and, inside
springboot-react-social-login
root folder, run the command belowdocker-compose down -v
-
In a terminal, make sure you are in
springboot-react-social-login/movie-ui
folder -
Run the following commands
npm upgrade npm i -g npm-check-updates ncu -u npm install