Quantcast
Channel: Blog – Stormpath User Identity API
Viewing all articles
Browse latest Browse all 278

Tutorial: Build a Spring Boot Application with React and User Authentication

$
0
0

Previously you created a CRUD application using Spring Boot, React and Stormpath where React handled the data view and the Stormpath Spring Boot Starter set up the login and registration pages. Now you’ll see how to use Stormpath’s React SDK to create login and signup pages manually so that every view on your site is managed by you.

Re-wire Stormpath and React

The Stormpath Spring Boot Starter sets up local server endpoints such as /login and /register that both serve up the front-end templates (for get requests) and receive back-end API requests (for post and put). You need to wire the get endpoints to your own React-based HTML. You will use the React Router to handle each URL, and the pages themselves will call the starter post and put endpoints when logging in, registering etc.

Configure Spring Boot and Stormpath

Start with a clone of the repository from a follow-on tutorial (which added webpack functionality):

git clone https://github.com/stormpath/stormpath-spring-boot-webpack-example

Strip out the security configuration by removing any Stormpath-related lines from application.properties. The file should then read

spring.data.rest.basePath=/api

Now rename the endpoints you want to override for the front-end so that your URLs don’t clash with the Spring Boot Starter.

spring.data.rest.basePath=/api
stormpath.web.login.uri=/signin
stormpath.web.register.uri=/signup
stormpath.web.forgotPassword.uri=/lostpass

Note: see the Stormpath documentation for a full list of these settings.

Remove the Stormpath code from configure() in Security.java.

@Configuration
public class Security extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    }
}

Install the project libraries and run webpack.

npm install
webpack 
mvn spring-boot:run

If you navigate to localhost:8080 you should see a table with some rows. This is what the user should see after they’ve logged in.

React Starter

Add Security with Stormpath for Authentication

Add the Stormpath-related lines back to application.properties.

stormpath.application.href = ...
stormpath.client.apiKey.id = ...
stormpath.client.apiKey.secret = ...

Note: For security reasons you should never store your Stormpath keys inside of project files. Rather, use environment variables or an apiKey.properties file.

Add the Stormpath lines back to Security.java but change it to allow anyone access the homepage, public files, and the URLs for the user management pages.

@Configuration
public class Security extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.apply(stormpath()).and()
        .authorizeRequests()
        .antMatchers("/","/public/**","/login","/register","/forgot").permitAll();
    }
}

Restart and you’ll see the table header and logout button but without any table rows. You’ve allowed anyone to view the main page but there isn’t any data coming through.

Network Failure

If you open the network console you’ll see what is happening—an authorization failure occurred on the /api/employees REST endpoint. You need to set up React to redirect to a login page when an authorization failure like this happens.

Create Routes in React

The Stormpath React SDK uses React Router to specify pages like login. Add these libraries to your project:

npm install --save react-stormpath react-router

Now add the following imports at the top of your app.js entry.

import ReactStormpath, { Router, AuthenticatedRoute, LoginRoute } from 'react-stormpath';
import { Route, browserHistory } from 'react-router';

These define which React components represent the login page, etc., and which URLs require authentication. Next initialize the SDK with the following after your imports:

ReactStormpath.init({
endpoints: {
  login: '/signin',
  register: ‘/signup’,
  forgotPassword: ‘/lostpass’
  }
});

The init accepts various settings to configure the SDK. Here the management endpoint URLs are changed to match those specified in application.properties. Change the render command at the bottom of app.js to the following:

ReactDOM.render(
  
    
    
  ,
  document.getElementById('root')
);

You’ve specified that the root element must render from Router (a Stormpath component) which uses React Router’s browserHistory plugin to manage URLs. Then AuthenticateRoute ensures that any visits to the homepage (/) need to be authenticated and also rendered with the MainPage component (you’ll derive this from the previous interface). Finally the LoginRoute makes sure that any login requirements redirect to /login and are rendered with a component called LoginPage (which you still need to define).

Create Pages in React

Put each page into a separate file. Inside of src create a folder called pages.

Pages Folder

Pull the previous components out of app.js and export them from MainPage.js.

import React from 'react';
import $ from 'jquery';
import toastr from 'toastr';

var Employee = React.createClass({

  getInitialState: function() {
    return {display: true };
  },
  handleDelete() {
    var self = this;
    $.ajax({
        url: self.props.employee._links.self.href,
        type: 'DELETE',
        success: function(result) {
          self.setState({display: false});
        },
        error: function(xhr, ajaxOptions, thrownError) {
          toastr.error(xhr.responseJSON.message);
        }
    });
  },
  render: function() {

    if (this.state.display==false) return null;
    else return (
      
          {this.props.employee.name}
          {this.props.employee.age}
          {this.props.employee.years}
          
            
          
      
    );
  }
});

var EmployeeTable = React.createClass({

  render: function() {

    var rows = [];
    this.props.employees.forEach(function(employee) {
      rows.push(
        );
    });

    return (
      
{rows}
Name Age Years Delete
); } }); var MainPage = React.createClass({ loadEmployeesFromServer: function() { var self = this; $.ajax({ url: "http://localhost:8080/api/employees", }).then(function(data) { self.setState({ employees: data._embedded.employees }); }); }, getInitialState: function() { return { employees: [] }; }, componentDidMount: function() { this.loadEmployeesFromServer(); }, render() { return (
); } }); export default MainPage;

Note: the main page now includes the logout button. This simplifies index.html, our single page app holder, significantly.



    React + Spring
    


    

Now create the login page in LoginPage.js.

import React from 'react';
import DocumentTitle from 'react-document-title';
import { LoginForm } from 'react-stormpath';

var LoginPage = React.createClass({

  render() {
    return (
      
        

Login


); } }); export default LoginPage;

Here you’re using the React Document Title library which you need to install. It allows you to set the browser title whilst using React Router.

npm install --save react-document-title

Now import the pages into your app.js entry.

import MainPage from './pages/MainPage';
import LoginPage from './pages/LoginPage';

app.js now looks like the following.

import React from 'react';
import ReactDOM from 'react-dom';

import ReactStormpath, { Router, AuthenticatedRoute, LoginRoute } from 'react-stormpath';
import { Route, browserHistory } from 'react-router';

import 'bootstrap/dist/css/bootstrap.css';
import 'toastr/build/toastr.css';

import MainPage from './pages/MainPage';
import LoginPage from './pages/LoginPage';

ReactStormpath.init({
  endpoints: {
    login: '/signin',
    register: ‘/signup’,
    forgotPassword: ‘/lostpass’
  }
});

ReactDOM.render(
  
    
    
  ,
  document.getElementById('root')
);

Reroute Through Spring Boot

React Router artificially alters the URL to /login, /register,etc., but all requests still come through Spring Boot (i.e. server). You need to tell Spring boot to send those requests to our SPA in case someone refreshes the browser window. Change HomeController.java to the following.

package tutorial;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HomeController {

    @RequestMapping(value = {"/","/login","/register","/forgot"})
    public String index() {
        return "index";
    }
}

Start Your Site

After running Webpack and refreshing you should be sent to the login page you just created.

Custom Login

Once you put in correct details you’ll see the data table populated as before.

Add Signup and Password Reset

There are two other pages you should specify – registration, and the forgot password screen. The first you can add using an ordinary React Router Route.

import RegisterPage from './pages/RegisterPage';
...

For the page itself, use the one from the React SDK example project.

import React from 'react';
import DocumentTitle from 'react-document-title';

import { RegistrationForm, LoginLink } from 'react-stormpath';

var RegisterPage = React.createClass({
  render() {
    return (
      
        

Registration


Your account has been created. Login Now.

Your account has been created. Please check your email for a verification link.

Back to Login

); } }); export default RegisterPage;

Add a link to the login page to /register.


Register

Now, when you click the link you should see a signup page.

Custom Signup

Add Forgot Password

Lastly, the forgot password page is configured in much the same way.

import React from 'react';
import DocumentTitle from 'react-document-title';

import { ResetPasswordForm } from 'react-stormpath';

var ForgotPage = React.createClass({
  render() {
    return (
      
        

Forgot Password


); } }); export default ForgotPage;

import ForgotPage from './pages/ForgotPage';
…

Learn More!

Just like that you have created your own React user management components and tied them to the Spring Boot backend. You can clone the full source code on Github. To go further, check out the Stormpath React SDK API for more details or check out this blog post on how to create custom forms with React.

The post Tutorial: Build a Spring Boot Application with React and User Authentication appeared first on Stormpath User Identity API.


Viewing all articles
Browse latest Browse all 278

Trending Articles