Monday, September 7, 2020

Basic Login ReactJs - OAuth2 - Axios

React - OAuth2 - Axios

I share basic example how to integrate React, OAuth2 and Axios, in this example i just share code how to implement on  front end of course you need to add css  if you want customize , if you want to know how to implement on backend, you can get example on my github, i used Kotlin or Java for backend. check in the end the post.

Create proyect react:

npx create-react-app login-react-oauth2-axios







Install Axios:

cd login-react-oauth2-axios

npm i axios




Create next folder and files, below of struct and check image

- components
        -login
             Files:
                    Login.js
        -menu
             Files:
                    Menu.js
-services 
        -auth
             Files:
                AuthService.js
        -util
             Files:
                Util.js

















I used class but you prefered, you can use Hooks .

Util.js: Is most import because when you sent request POST, GET, DELETE or something like that add on header your token, for open your web service on backend.

Add next code. (change the url)

For example in my code, my context of my backend is services, i created two const because the first const restApi i used for call all my web services, when i call web service automatically inject header authorization with interceptors, and second const authUrl i used for get my first token from backend.


import axios from "axios";

const restApi = axios.create({
    baseURL: 'http://localhost:9000/services'
})

const authUrl  = 'http://localhost:9000/services/oauth/token';

restApi.interceptors.request.use(function(config){
    console.log("request send");
    let token = sessionStorage.getItem('token');
    config.headers.Authorization = `Bearer ${token}`;
    return config;
})
export {restApiauthUrl}


AuthService.js: I save first token, you have to add YOUR_CLIENT and YOUR SECRET of your backend on btoa.

import { Component } from "react";
import axios from "axios";
import { authUrl } from "../util/Util";

class AuthService extends Component {
  login(json) {
    const headers = {
      Authorization: "Basic " + btoa("YOUR_CLIENT:YOUR_SECRET"),
      "Content-type": "application/x-www-form-urlencoded",
    };

    return axios({
      method: "POST",
      url: authUrl,
      params: {
        username: json.username,
        password: json.password,
        grant_type: "password",
      },
      headers: headers,
    });
  }

  user(accessToken) {
    const payload = this.getDataToken(accessToken);
    return payload.username;
  }

  saveToken(accessToken) {
    sessionStorage.setItem("token"accessToken);
  }

  getDataToken(accessToken) {
    if (accessToken) {
      console.log(JSON.parse(atob(accessToken.split(".")[1])));
      return JSON.parse(atob(accessToken.split(".")[1]));
    }
    return null;
  }

  isAuthenticated() {
    let token = sessionStorage.getItem("token");
    const payload = this.getDataToken(token);
    if (payload != null && payload.username && payload.username.length > 0) {
      return true;
    }
    return false;
  }
}

const authService = new AuthService();

export default authService;



Menu.js: If you login with credetencial correct and display your username.

import React, { Component } from "react";
import authService from "../../services/auth/AuthService";

class Menu extends Component {
  constructor(props) {
    super(props);

    this.state = {
      username: "",
    };
  }

  componentWillMount() {
    let token = sessionStorage.getItem("token");
    let username = authService.user(token);
    this.setState({
      username: username,
    });
  }
  render() {
    return <div>Welcome {this.state.username}</div>;
  }
}

export default Menu;


Login.js: add next code on login.

import React, { Component } from "react";

import Menu from "../menu/Menu";

import authService from "../../services/auth/AuthService";

class Login extends Component {
  constructor(props) {
    super(props);

    this.state = {
      username: "",
      password: "",
      authenticated: false,
    };
  }

  changeHandler = (event=> {
    this.setState({ [event.target.name]: event.target.value });
  };

  submitHandler = (e=> {
    e.preventDefault();

    authService
      .login(this.state)
      .then((response=> {
        authService.saveToken(response.data.access_token);
        this.setState({
          authenticated: true,
        });
      })
      .catch((error=> {
        console.log(error);
      });
  };

  render() {
    if (this.state.authenticated) {
      return (
        <div>
          <Menu></Menu>
        </div>
      );
    } else {
      const { usernamepassword } = this.state;
      return (
        <div>
          <form onSubmit={this.submitHandler}>
            <div>
              <input
                type="text"
                name="username"
                value={username}
                onChange={this.changeHandler}
              ></input>
            </div>
            <div>
              <input
                type="password"
                name="password"
                value={password}
                onChange={this.changeHandler}
              ></input>
            </div>
            <button type="submit">Login</button>
          </form>
        </div>
      );
    }
  }
}

export default Login;


And the last

App.js:  Add the next code.

import React, { Component } from "react";
import Login from "./components/login/Login";
import Menu from "./components/menu/Menu";
import authService from "./services/auth/AuthService";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      authenticated: false,
    };
  }

  componentWillMount() {
    let isAuth = authService.isAuthenticated();
    console.log(isAuth);

    this.setState({
      authenticated: isAuth,
    });
  }

  render() {
    if (this.state.authenticated) {
      return (
        <div>
          <Menu></Menu>
        </div>
      );
    } else {
      return (
        <div>
          <Login></Login>
        </div>
      );
    }
  }
}

export default App;


Test:

npm start








Code on GitHub:















No comments:

Post a Comment

Provisioning Cloud SQL with Private Service Connect Using Terraform & Accessing from Cloud Run with Spring Boot

In this post, we'll explore how to provision Cloud SQL instances with Private Service Connect (PSC) connectivity using Terraform and the...