1
0
mirror of https://github.com/sasjs/server.git synced 2026-01-07 06:30:06 +00:00

feat: enabled session based authentication for web

This commit is contained in:
Saad Jutt
2022-04-28 06:44:25 +05:00
parent a30fb1a241
commit 5da93f318a
25 changed files with 582 additions and 300 deletions

View File

@@ -1,3 +1,4 @@
import axios from 'axios'
import React, { useState, useContext } from 'react'
import { useLocation } from 'react-router-dom'
import PropTypes from 'prop-types'
@@ -5,34 +6,11 @@ import PropTypes from 'prop-types'
import { CssBaseline, Box, TextField, Button, Typography } from '@mui/material'
import { AppContext } from '../context/appContext'
const headers = {
Accept: 'application/json',
'Content-Type': 'application/json'
}
const NODE_ENV = process.env.NODE_ENV
const PORT_API = process.env.PORT_API
const baseUrl =
NODE_ENV === 'development' ? `http://localhost:${PORT_API ?? 5000}` : ''
const getAuthCode = async (credentials: any) =>
axios.post('/SASjsApi/auth/authorize', credentials).then((res) => res.data)
const getAuthCode = async (credentials: any) => {
return fetch(`${baseUrl}/SASjsApi/auth/authorize`, {
method: 'POST',
headers,
body: JSON.stringify(credentials)
}).then(async (response) => {
const resText = await response.text()
if (response.status !== 200) throw resText
return JSON.parse(resText)
})
}
const getTokens = async (payload: any) => {
return fetch(`${baseUrl}/SASjsApi/auth/token`, {
method: 'POST',
headers,
body: JSON.stringify(payload)
}).then((data) => data.json())
}
const login = async (payload: { username: string; password: string }) =>
axios.post('/login', payload).then((res) => res.data)
const Login = ({ getCodeOnly }: any) => {
const location = useLocation()
@@ -47,34 +25,40 @@ const Login = ({ getCodeOnly }: any) => {
error = false
setErrorMessage('')
e.preventDefault()
let clientId = process.env.CLIENT_ID ?? localStorage.getItem('CLIENT_ID')
if (getCodeOnly) {
const params = new URLSearchParams(location.search)
const responseType = params.get('response_type')
if (responseType === 'code') clientId = params.get('client_id')
if (responseType === 'code') {
const clientId = params.get('client_id')
const { code } = await getAuthCode({
clientId,
username,
password
}).catch((err: any) => {
error = true
setErrorMessage(err.response.data)
return {}
})
if (!error) return setDisplayCode(code)
return
}
}
const { code } = await getAuthCode({
clientId,
const { loggedIn, user } = await login({
username,
password
}).catch((err: string) => {
}).catch((err: any) => {
error = true
setErrorMessage(err)
setErrorMessage(err.response.data)
return {}
})
if (!error) {
if (getCodeOnly) return setDisplayCode(code)
const { accessToken, refreshToken } = await getTokens({
clientId,
code
})
if (appContext.setTokens) appContext.setTokens(accessToken, refreshToken)
if (appContext.setUserName) appContext.setUserName(username)
if (loggedIn) {
appContext.setLoggedIn?.(loggedIn)
appContext.setUserName?.(user.username)
appContext.setDisplayName?.(user.displayname)
}
}
@@ -129,7 +113,11 @@ const Login = ({ getCodeOnly }: any) => {
required
/>
{errorMessage && <span>{errorMessage}</span>}
<Button type="submit" variant="outlined" disabled={!appContext.setTokens}>
<Button
type="submit"
variant="outlined"
disabled={!appContext.setLoggedIn}
>
Submit
</Button>
</Box>

View File

@@ -1,94 +0,0 @@
import axios from 'axios'
import { useEffect, useState } from 'react'
export default function useTokens() {
const getTokens = () => {
const accessToken = localStorage.getItem('accessToken')
const refreshToken = localStorage.getItem('refreshToken')
if (accessToken && refreshToken) {
setAxiosRequestHeader(accessToken)
return { accessToken, refreshToken }
}
return undefined
}
const [tokens, setTokens] = useState(getTokens())
useEffect(() => {
if (tokens === undefined) {
localStorage.removeItem('accessToken')
localStorage.removeItem('refreshToken')
}
}, [tokens])
setAxiosResponse(setTokens)
const saveTokens = (accessToken: string, refreshToken: string) => {
localStorage.setItem('accessToken', accessToken)
localStorage.setItem('refreshToken', refreshToken)
setAxiosRequestHeader(accessToken)
setTokens({ accessToken, refreshToken })
}
return {
setTokens: saveTokens,
tokens
}
}
const NODE_ENV = process.env.NODE_ENV
const PORT_API = process.env.PORT_API
const baseUrl =
NODE_ENV === 'development' ? `http://localhost:${PORT_API ?? 5000}` : ''
const isAbsoluteURLRegex = /^(?:\w+:)\/\//
const setAxiosRequestHeader = (accessToken: string) => {
axios.interceptors.request.use(function (config) {
if (baseUrl && !isAbsoluteURLRegex.test(config.url as string)) {
config.url = baseUrl + config.url
}
config.headers!['Authorization'] = `Bearer ${accessToken}`
config.withCredentials = true
return config
})
}
const setAxiosResponse = (setTokens: Function) => {
// Add a response interceptor
axios.interceptors.response.use(
function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
return response
},
async function (error) {
if (error.response?.status === 401) {
// refresh token
// const { accessToken, refreshToken: newRefresh } = await refreshMyToken(
// refreshToken
// )
// if (accessToken && newRefresh) {
// setTokens(accessToken, newRefresh)
// error.config.headers['Authorization'] = 'Bearer ' + accessToken
// error.config.baseURL = undefined
// return axios.request(error.config)
// }
setTokens(undefined)
}
return Promise.reject(error)
}
)
}
// const refreshMyToken = async (refreshToken: string) => {
// return fetch('http://localhost:5000/SASjsApi/auth/refresh', {
// method: 'POST',
// headers: {
// Authorization: `Bearer ${refreshToken}`
// }
// }).then((data) => data.json())
// }