React authentication with JWT - reactjs

I am trying to add an authentication system to my application in React / Laravel. For that I make a request for the theory recovers a token as on Passport. The problem is that it returns me a token undefined ... Yet when I look at the console of my browser I see in preview the token in question ...
Can someone please guide me to solve this problem?
Here is the code of my Auth service
import decode from 'jwt-decode';
export default class AuthService {
// Initializing important variables
constructor(domain) {
this.domain = domain || 'http://127.0.0.1:8000' // API server
domain
this.fetch = this.fetch.bind(this) // React binding stuff
this.login = this.login.bind(this)
this.getProfile = this.getProfile.bind(this)
}
login(username, password) {
// Get a token from api server using the fetch api
return this.fetch(`${this.domain}/oauth/token`, {
method: 'POST',
body: JSON.stringify({
username,
password,
grant_type: "password",
client_id:"2",
client_secret : "Wu07Aqy9pU5pLO9ooTsqYDBpOdzGwrhvw5DahcEo"
})
}).then(res => {
this.setToken(res.token) // Setting the token in localStorage
return Promise.resolve(res);
})
}
loggedIn() {
// Checks if there is a saved token and it's still valid
const token = this.getToken() // GEtting token from localstorage
return !!token && !this.isTokenExpired(token) // handwaiving here
}
isTokenExpired(token) {
try {
const decoded = decode(token);
if (decoded.exp < Date.now() / 1000) { // Checking if token is
expired. N
return true;
}
else
return false;
}
catch (err) {
return false;
}
}
setToken(token) {
// Saves user token to localStorage
localStorage.setItem('access_token', token)
}
getToken() {
// Retrieves the user token from localStorage
return localStorage.getItem('access_token')
}
logout() {
// Clear user token and profile data from localStorage
localStorage.removeItem('access_token');
}
getProfile() {
// Using jwt-decode npm package to decode the token
return decode(this.getToken());
}
fetch(url, options) {
// performs api calls sending the required authentication headers
const headers = {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
// Setting Authorization header
// Authorization: Bearer xxxxxxx.xxxxxxxx.xxxxxx
if (this.loggedIn()) {
headers['Authorization'] = 'Bearer ' + this.getToken()
}
return fetch(url, {
headers,
...options
})
.then(this._checkStatus)
.then(response => response.json())
}
_checkStatus(response) {
// raises an error in case response status is not a success
if (response.status >= 200 && response.status < 300) { // Success
status lies between 200 to 300
return response
} else {
var error = new Error(response.statusText)
error.response = response
throw error
}
}
}
Here of my form
import React, { Component } from 'react';
import AuthService from './AuthService';
import { Router, Route, Switch, Link } from 'react-router-dom'
class Login extends Component {
constructor(){
super();
this.handleChange = this.handleChange.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.Auth = new AuthService();
}
handleFormSubmit(e){
e.preventDefault();
this.Auth.login(this.state.username,this.state.password)
.then(res =>{
this.props.history.replace('/Localisations');
})
.catch(err =>{
alert(err);
})
}
componentWillMount(){
if(this.Auth.loggedIn())
this.props.history.replace('/');
}
render() {
return (
<div className="center">
<div className="card">
<h1>Login</h1>
<form onSubmit={this.handleFormSubmit}>
<input
className="form-item"
placeholder="Username goes here..."
name="username"
type="text"
onChange={this.handleChange}
/>
<input
className="form-item"
placeholder="Password goes here..."
name="password"
type="password"
onChange={this.handleChange}
/>
<input
className="form-submit"
value="Submit"
type="submit"
/>
</form>
</div>
</div>
);
}
handleChange(e){
this.setState(
{
[e.target.name]: e.target.value
}
)
}
}
export default Login;
And here of of my with Auth
import React, { Component } from 'react';
import AuthService from './AuthService';
export default function withAuth(AuthComponent) {
const Auth = new AuthService('http://127.0.0.1:8000');
return class AuthWrapped extends Component {
constructor() {
super();
this.state = {
user: null
}
}
componentWillMount() {
if (!Auth.loggedIn()) {
this.props.history.push('/Localisations')
}
else {
try {
const profile = Auth.getProfile()
this.setState({
user: profile
})
}
catch(err){
Auth.logout()
this.props.history.push('/')
}
}
}
render() {
if (this.state.user) {
return (
<AuthComponent history={this.props.history} user= .
{this.state.user} />
)
}
else {
return null
}
}
};
}

Related

How do I persist my next-auth user session? so i could use the ID provided to fetch data in other routes

What I want to achieve here is, whenever a user logs in, I want to store the data returned because the data holds an ID that I would use to fetch data in other routes.
When a user successfully logs in, he would be redirected to the /home route and the ID gotten from the session would be used to fetch data. Everything works fine initially, but if I refresh the home page, the user becomes null.
This is what my [...nextauth].js looks like.
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import axios from "axios";
export default NextAuth({
providers: [
CredentialsProvider({
name: "credentials",
credentials: {
username: { label: "Username", type: "text", placeholder: "justin" },
password: {label: "Password",type: "password",placeholder: "******"},
},
async authorize(credentials, req) {
const url = req.body.callbackUrl.split("/auth")[0];
const { username, password } = credentials;
const user = await axios({
url: `${url}/api/user/login`,
method: "POST",
data: {
username: username,
password: password,
},
"content-type": "application/json",
})
.then((res) => {
return res.data;
})
.catch((err) => {
if (err.response.data) {
throw new Error(err.response.data);
} else {
return null;
}
return null;
});
return user;
},
}),
],
callbacks: {
jwt: ({ token, user }) => {
if (user) {
token.user = user;
}
return token;
},
session: ({ session, token }) => {
if (token) {
session.user = token.user;
}
return session;
},
},
pages: {
signIn: "/auth/login",
newUser: "/auth/register",
},
});
and this is what my /home route looks like
import Card from "#/components/card/Card";
import React, { useEffect, useState } from "react";
import styles from "./home.module.css";
import { Ubuntu } from "#next/font/google";
import { useSession } from "next-auth/react";
import { useDispatch, useSelector } from "react-redux";
const ubuntu = Ubuntu({ weight: "500", subsets: ["cyrillic"] });
const getData = async (id) => {
const res = await fetch({
url: "http://localhost:3000/api/note/getall",
method: "POST",
"content-type": "application/json",
data: {
id: id,
},
});
if (!res.ok) {
console.log(id);
throw new Error("Unable to fetch");
} else {
return res.json();
console.log(res);
}
};
function home() {
const colors = ["#E9F5FC", "#FFF5E1", "#FFE9F3", "#F3F5F7"];
const random = Math.floor(Math.random() * 5);
const rc = colors[random];
const [pop, setPop] = useState("none");
const { user } = useSelector((state) => state.user);
const getDataa = async () => {
console.log(user)
const data = await getData(user._id);
console.log(data);
};
useEffect(() => {
if (user) {
alert(user)
}
}, []);
return (
<div className={styles.home}>
<header>
<h3 className={ubuntu.className}>
Hello, <br /> {user?.username}!
</h3>
<input type="text" placeholder="search" />
</header>
<div className={styles.nav}>
<h1 className={ubuntu.className}>Notes</h1>
</div>
<div className={styles.section}>
<div className={styles.inner}>
{/* {data &&
data.map((e) => (
<Card
rawData={e}
color={colors[Math.floor(Math.random() * colors.length)]}
/>
))} */}
</div>
</div>
<div className="new"></div>
</div>
);
}
export default home;
Add this component to your App.js file :
function Auth({ children }) {
const router = useRouter();
const { status } = useSession({
required: true,
onUnauthenticated() {
router.push("/sign-in");
},
});
if (status === "loading") {
return <div>Loading ...</div>;
}
return children;
}
Now in your App function instead of returning <Component {...pageProps} /> you check first if the component has auth property, so you wrapp it with <Auth> to ensure that every component that requires session will only mount when the session finishes loading (that's why the user is null because the session is still loading)
{
Component.auth ? (
<Auth>
<Component {...pageProps} />
</Auth>
) : (
<Component {...pageProps} />
);
}
finally you add .auth = {} to every page in whitch you want the session to be defined (Home in your case)
const Home = () => {
//....
}
Home.auth = {};
This also helps to redirect user to /sign-in page if the session is expired
This code seems like it would create a problem / race-condition since you're mixing two different async promise handling styles:
const user = await axios({
url: `${url}/api/user/login`,
method: "POST",
data: {
username: username,
password: password,
},
"content-type": "application/json",
})
.then((res) => {
return res.data;
})
.catch((err) => {
if (err.response.data) {
throw new Error(err.response.data);
} else {
return null;
}
return null;
});
return user;
It should either be this:
try {
const user = await axios({
url: `${url}/api/user/login`,
method: "POST",
data: {
username: username,
password: password,
},
"content-type": "application/json",
});
return user.data;
} catch (err) {
if (err.response.data) {
throw new Error(err.response.data);
} else {
return null;
}
}
Or this:
axios({
url: `${url}/api/user/login`,
method: "POST",
data: {
username: username,
password: password,
},
"content-type": "application/json",
}).then((res) => {
return res.data;
}).catch((err) => {
if (err.response.data) {
throw new Error(err.response.data);
} else {
return null;
}
return null;
});

React Js : Unable to login until page gets refresh manually

As a beginner to the React Js I'm trying simple projects for hands-on experience and to learn as well! so, in the same way I've created one login portal with react js and WAMP server by watching YouTube tutorial
in the middle I went through some errors but somehow I managed and get them off but after completing the project when I'm trying to login with the credentials which I've given in database the response and all was clear but the page doesn't redirect to welcome page after clicking on login button instead it redirects to welcome page after refreshing manually. I couldn't identify the mistake in my code.
LoginForm.js
import React from 'react';
import InputField from './InputField';
import SubmitButton from './SubmitButton';
import UserStore from './stores/UserStore';
class LoginForm extends React.Component {
constructor(props) {
super(props);
this.state = {
username: "",
password: "",
buttonDisabled: false
}
}
setInputValue(property, val) {
val = val.trim();
if (val.length > 12) {
return;
}
this.setState({
[property]: val
})
}
resetForm() {
this.setState({
username: "",
password: "",
buttonDisabled: false
})
}
async doLogin() {
if (!this.state.username) {
return;
}
if (!this.state.password) {
return;
}
this.setState({
buttonDisabled: true
})
try {
let res = await fetch('/login', {
method: "post",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password
})
});
let result = await res.json();
if (result && result.succes) {
UserStore.isLoggedIn = true;
UserStore.username = result.username;
}
else if (result && result.succes === false) {
this.resetForm();
alert(result.msg);
}
} catch (e) {
console.log(e);
this.resetForm();
}
}
render() {
return (
<div className="loginForm">
Log In
<InputField
type='text'
placeholder='Username'
value={this.state.username ? this.state.username : ''}
onChange={(val) => this.setInputValue('username', val)}
/>
<InputField
type='password'
placeholder='Password'
value={this.state.password ? this.state.password : ''}
onChange={(val) => this.setInputValue('password', val)}
/>
<SubmitButton
text='Log In'
disabled={this.state.buttonDisabled}
onClick={() => this.doLogin()}
/>
</div>
);
}
}
export default LoginForm;
SubmitButton.js
import React from 'react';
class SubmitButton extends React.Component {
render() {
return (
<div className="submitButton">
<button
className='btn'
type='submit'
disabled={this.props.disabled}
onClick={() => this.props.onClick()}
>
{this.props.text}
</button>
</div>
);
}
}
export default SubmitButton;
App.js
import React from 'react';
import { observer } from 'mobx-react';
import UserStore from './stores/UserStore';
import LoginForm from './LoginForm';
import SubmitButton from './SubmitButton';
import './App.css';
class App extends React.Component {
async componentDidMount() {
try {
let res = await fetch('/isLoggedIn', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
let result = await res.json();
if (result && result.success) {
UserStore.loading = false;
UserStore.isLoggedIn = true;
UserStore.username = result.username;
}
else {
UserStore.loading = false;
UserStore.isLoggedIn = false;
}
}
catch (e) {
UserStore.loading = false;
UserStore.isLoggedIn = false;
}
}
async doLogout() {
try {
let res = await fetch('/logout', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-type': 'application/json'
}
});
let result = await res.json();
if (result && result.success) {
UserStore.isLoggedIn = false;
UserStore.username = '';
}
}
catch (e) {
console.log(e);
}
}
render() {
if (UserStore.loading) {
return (
<div className="app">
<div className='container'>
Loading ,Please Wait...
</div>
</div>
);
}
else {
if (UserStore.isLoggedIn) {
return (
<div className="app">
<div className='container'>
Welcome {UserStore.username}
<SubmitButton
text={'Log Out'}
disabled={false}
onClick={() => this.doLogout()}
/>
</div>
</div>
);
}
return (
<div className="app">
<div className='container'>
<LoginForm />
</div>
</div>
);
}
}
}
export default observer(App);
Router.js
const bcrypt = require('bcrypt');
class Router {
constructor(app, db) {
this.login(app, db);
this.logout(app, db);
this.isLoggedIn(app, db);
}
login(app, db) {
app.post('/login', (req, res) => {
let username = req.body.username;
let password = req.body.password;
username = username.toLowerCase();
if (username.length > 12 || password.length > 12) {
res.json({
success: false,
msg: 'An error occured,please try again'
})
return;
}
let cols = [username];
db.query('SELECT * FROM user WHERE username =? LIMIT 1', cols, (err, data, fields) => {
if (err) {
res.json({
success: false,
msg: 'An error occured,please try again'
});
return;
}
if (data && data.length === 1) {
bcrypt.compare(password, data[0].password, (bcryptErr, verified) => {
if (verified) {
req.session.userID = data[0].id;
res.json({
success: true,
username: data[0].username
})
return;
}
else {
res.json({
success: false,
msg: 'Invalid Password'
})
}
});
} else {
res.json({
success: false,
msg: 'User not Found,please try again..!'
})
}
});
});
}
logout(app, db) {
app.post('/logout',(req,res)=>{
if(req.session.userID){
req.session.destroy();
res.json({
success:true
})
return true;
}
else{
res.json({
success:false
})
return false;
}
})
}
isLoggedIn(app, db) {
app.post('/isLoggedIn',(req,res)=>{
if(req.session.userID){
let cols =[req.session.userID];
db.query('SELECT * FROM user WHERE ID=? LIMIT 1',cols,(err,data,fields) =>{
if(data && data.length ===1){
res.json({
success:true,
username:data[0].username
});
return true;
}
else{
res.json({
success:false
});
}
});
}
else{
res.json({
success:false
})
}
});
}
}
module.exports = Router;
you have to change some logic in LoginForm.js. There are multiple ways in which you can do that. I am showing you one example.
import React from 'react';
import InputField from './InputField';
import SubmitButton from './SubmitButton';
import UserStore from './stores/UserStore';
import {Redirect} from 'react-router-dom' //add a redirect from react-router-dom
class LoginForm extends React.Component {
constructor(props) {
super(props);
this.state = {
username: "",
password: "",
buttonDisabled: false,
redirectToRefer : false //add a state here for redirect
}
}
setInputValue(property, val) {
val = val.trim();
if (val.length > 12) {
return;
}
this.setState({
[property]: val
})
}
resetForm() {
this.setState({
username: "",
password: "",
buttonDisabled: false
})
}
async doLogin() {
if (!this.state.username) {
return;
}
if (!this.state.password) {
return;
}
this.setState({
buttonDisabled: true
})
try {
let res = await fetch('/login', {
method: "post",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password
})
});
let result = await res.json();
if (result && result.succes) {
UserStore.isLoggedIn = true;
UserStore.username = result.username;
this.setState({redirectToRefer:true})//set rediectToRefer as true
}
else if (result && result.succes === false) {
this.resetForm();
alert(result.msg);
}
} catch (e) {
console.log(e);
this.resetForm();
}
}
render() {
//add a condition at render if redirectToRefer is true then redirect to your page
if(redirectToRefer)
{
return <Redirect to ="/"/>
}
return (
<div className="loginForm">
Log In
<InputField
type='text'
placeholder='Username'
value={this.state.username ? this.state.username : ''}
onChange={(val) => this.setInputValue('username', val)}
/>
<InputField
type='password'
placeholder='Password'
value={this.state.password ? this.state.password : ''}
onChange={(val) => this.setInputValue('password', val)}
/>
<SubmitButton
text='Log In'
disabled={this.state.buttonDisabled}
onClick={() => this.doLogin()}
/>
</div>
);
}
}
export default LoginForm;

undefined is not a function in React Native

I'm trying to make an API call in React Native to handle user authentication. I'm passing this.state.email and this.state.password (both bound to text inputs) to a function in my services/ folder, where the call is made. Afterwards, the screen should navigate to the home stack or return an error. This is my login screen code:
import AuthService from ...
export default class LoginScreen extends Component {
constructor(props) {
super(props);
this.login = this.login.bind(this);
this.state = {
email: '',
password: '',
};
}
login() {
AuthService.login(this.state.email, this.state.password)
.then(this.props.navigation.navigate('Main')) //Move to home screen
.catch(console.error('Error')); //Handle error
}
render() {
return (
<View>
<TextInput
onChangeText={email => this.setState({ email })}
value={this.state.email}
/>
<TextInput
onChangeText={password => this.setState({ password })}
value={this.state.password}
/>
<TouchableOpacity onPress={this.login}>
<Text style={styles.text}>Submit</Text>
</TouchableOpacity>
</View>
);
}
}
And this is my AuthService function:
login(email, password) {
// Check if credentials exist
if (!email || !password) {
return undefined;
}
return fetch(
`${AUTH_ROOT}/login`,
{
method: 'POST',
body: { email, password },
}
.then(
res => {
const data = { ...res.data };
if (!data) {
throw new Error('No user returned from auth service');
}
},
res => {
context.error = 'Could not login';
console.log(res);
}
)
);
},
But I'm getting the error:
> undefined is not a function (near '...{
> method: 'POST',
> body: {
> email: email,
> password: password,
> } }.then...')
What does this mean? Is my call not done correctly?
login(email, password) {
// Check if credentials exist
if (!email || !password) {
return undefined;
}
return fetch(
`${AUTH_ROOT}/login`,
{
method: 'POST',
body: { email, password },
}
)
.then(
res => {
const data = { ...res.data };
if (!data) {
throw new Error('No user returned from auth service');
}
},
res => {
context.error = 'Could not login';
console.log(res);
}
)
},
The right syntax for fetch is
fetch(url, params).then()
instead you had
fetch(url, params.then())

Passing data from fetch to another component

I have a Login component, which has form with inputs for user's data, and I have a method onFormSubmit with fetch. The problem is that I have no idea, how to pass token to another component ( it is there, I can console.log it ). The reason why I want to pass token to another component is that the other component is validating if user has logged in and by detecting token ( null = user didn't log in and redirect him to login page, otherwise go to protected pages )
My login.js component
class Login extends React.Component() {
constructor() {
super();
this.state = {
email: '',
password: '',
};
}
onInputChange = (e) => {
this.setState({
[e.target.id]: e.target.value
});
};
onFormSubmit = (e) => {
e.preventDefault();
fetch('http://localhost:3001/user/login', {
method: 'POST',
body: JSON.stringify({
email: this.state.email,
password: this.state.password
}),
headers: {
'Content-Type': 'application/json'
}
})
.then( res => {
if( res.status === 200){
this.props.history.push('/MyPlaces');
} else {
const error = new Error(res.error);
throw error;
}
})
.catch(err => {
console.error(err);
alert('Error login in please try again!');
});
};
render() {
return (
<div className="loginPanel">
<form onSubmit={this.onFormSubmit}>
<label>Email
<input type="text"
id="email"
value={this.state.email}
onChange={this.onInputChange}
/>
</label>
<label>Password
<input type="text"
id="password"
value={this.state.password}
onChange={this.onInputChange}/>
</label>
<input type="submit" value="Submit" />
</form>
</div>
);
};
}
export default Login;
My authentication component
import React, {Component} from 'react';
import { Redirect } from 'react-router-dom';
export default function withAuth(ComponentToProtect, props) {
return class extends Component {
constructor() {
super();
this.state = {
loading: true,
redirect: false
};
}
componentDidMount() {
fetch('')
.then(res => {
if( res.status === 200) {
this.setState({ loading: false});
} else {
const error = new Error(res.error);
throw error;
}
})
.catch(err => {
console.error(err);
this.setState({ loading: false, redirect: true });
})
}
render() {
const { loading, redirect } = this.state;
if( loading ){
return null;
}
if( redirect ){
return <Redirect to="/Login" />;
}
return (
<React.Fragment>
<ComponentToProtect {...this.props}/>
</React.Fragment>
);
}
}
}
I know that there is nothing in fetch in authentication component, I thought that I should've make another api request ( same as in login component, then after fetch just invoke
.then(res => res.json()).then(res => {
let token = res.token;
console.log("token: ", token);
});
but it just doesn't seem to be good idea I think. Could you please give me some guide how may I do that?
You can simply use localStorage.setItem('token-name', token); to store the token after fetch. Then you can retrieve it using localStorage.getItem('token-name') across all the component. If the getItem returns null then you can simply redirect to login.
For logout, you can simply update the token value to null.
Login Component
fetch('http://localhost:3001/user/login', {
method: 'POST',
body: JSON.stringify({
email: this.state.email,
password: this.state.password
}),
headers: {
'Content-Type': 'application/json'
}
})
.then(res => {
if( res.status === 200){
localStorage.setItem('token', res.token); //storing the token in localStorage.
this.props.history.push('/MyPlaces');
} else {
const error = new Error(res.error);
throw error;
}
})
.catch(err => {
console.error(err);
alert('Error login in please try again!');
});
Authentication Component
componentDidMount() {
let token = localStorage.getItem('token'); //retriving the token from localStorage
if(token === null){
this.setState({ loading: false, redirect: true });
}
}
Hope this will help you.

React render run before fetch method receives token from server

I have a JS file within my React application, which connects to the server, sends username and password, receives an oauth token from the server and stores the token in the local storage.
However before the token received by react, the react sends the next request before token stored in the local storage. Which leads to 401 unauthorized access.
AuthService.js
login(username, password) {
console.log(username);
return this.fetch(`${this.domain}/api/AuthAPI/getCredentials`, {
headers: {
'Access-Control-Allow-Origin': "*"
}
}).then(res => {
this.fetch(`${this.domain}/Token`, {
method: 'POST',
body: 'grant_type=password&username=' + res[0]
}).then(response => {
var date_token_issue = new Date();
this.setToken(response.access_token,response.expires_in, date_token_issue) // Setting the token in localStorage
return Promise.resolve(response);
})
})
}
setToken(idToken,expires, date_token_issue ) {
localStorage.setItem('id_token', idToken)
localStorage.setItem('expires', expires)
localStorage.setItem('date_token_issue', date_token_issue)
}
SignIn.jsx
import React, { Component } from 'react'
import AuthService from '../comonents/AuthService';
import Orders from '../../app/orders/orders'
import { Redirect, Switch, Route} from "react-router-dom";
export default function SignIn(AuthComponent){
const Auth = new AuthService('http://localhost:53050');
return class AuthWrapped extends Component {
constructor() {
super();
this.state = {
user: null,
loggedIn: false
}
}
async componentDidMount() {
if (!Auth.loggedIn()) {
const promise = await Auth.login('m.dawaina', 'm.dawaina');
console.log(promise)
this.setState({loggedIn: true});
}
else {
try {
this.setState({loggedIn: true})
const profile = Auth.getProfile()
this.setState({
user: profile
})
}
catch(err){
Auth.logout()
//this.props.history.replace('/login')
}
}
}
render() {
if (this.state.loggedIn) {
return (
<div>
<Redirect to='/orders'/>
<Switch>
<Route path="/orders" component={Orders} />
</Switch>
</div>
)
}
else {
return (
<AuthComponent history={this.props.history} user={this.state.user} />
)
}
}
}
}
I need a way to force react wait for the JS receives the token and stores it in the local storage, and prevent react sending the next request until it finds the token stored in the local storage.
login(username, password) {
console.log(username);
return this.fetch(`${this.domain}/api/AuthAPI/getCredentials`, {
headers: {
'Access-Control-Allow-Origin': "*"
}
}).then(res => {
// Add a return here
return this.fetch(`${this.domain}/Token`, {
method: 'POST',
body: 'grant_type=password&username=' + res[0]
}).then(response => {
var date_token_issue = new Date();
this.setToken(response.access_token,response.expires_in, date_token_issue) // Setting the token in localStorage
return Promise.resolve(response);
})
})
You need to add a return to the then function so that await will wait for the inner promise to resolve.

Resources