add validate token on component did mount
This commit is contained in:
parent
bafdfcc21b
commit
978a1cea6a
@ -6,7 +6,7 @@ const App = () => {
|
||||
return <FormLogin/>
|
||||
}
|
||||
|
||||
const authUrl = 'http://localhost:8080/authenticate'
|
||||
const authUrl = 'http://dummyspringtoken-env-1.eba-hfxxdsvk.us-east-2.elasticbeanstalk.com/authenticate'
|
||||
|
||||
export default wrapAuthContext(App, {
|
||||
authUrl
|
||||
|
@ -42,7 +42,11 @@ const FormLogin = () => {
|
||||
/>
|
||||
<button type={'submit'}>Submit</button>
|
||||
</form>
|
||||
<br/>
|
||||
<br />
|
||||
|
||||
<pre>
|
||||
{JSON.stringify(auth)}
|
||||
</pre>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -2400,10 +2400,6 @@ balanced-match@^1.0.0:
|
||||
resolved "https://npm-registry.cubetiqs.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||
|
||||
"base-context-provider@link:../../base-context-provider":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
base64-js@^1.0.2:
|
||||
version "1.3.1"
|
||||
resolved "https://npm-registry.cubetiqs.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "auth-context-provider",
|
||||
"version": "1.0.1-b",
|
||||
"version": "1.0.1-d",
|
||||
"description": "Made with create-react-library",
|
||||
"author": "vuthpov",
|
||||
"license": "MIT",
|
||||
|
@ -1,6 +1,7 @@
|
||||
interface TokenInstance {
|
||||
getToken: () => string
|
||||
setToken: (token: string) => void
|
||||
getAdditionalDataForTokenValidation: (key: string) => any
|
||||
}
|
||||
|
||||
const tokenKey = 'token'
|
||||
@ -13,6 +14,10 @@ class LocalStorageToken implements TokenInstance {
|
||||
setToken = (token: string) => {
|
||||
localStorage.setItem(tokenKey, token)
|
||||
}
|
||||
|
||||
getAdditionalDataForTokenValidation = (key: string) => {
|
||||
return localStorage.getItem(key)
|
||||
}
|
||||
}
|
||||
|
||||
export { LocalStorageToken, TokenInstance }
|
||||
|
116
src/index.tsx
116
src/index.tsx
@ -9,16 +9,27 @@ import ResponseError from './ResponseError'
|
||||
|
||||
export interface AuthContextProps {
|
||||
authUrl: string
|
||||
validateUrl: string
|
||||
keysPropertyToValidate?: string[]
|
||||
storageType?: 'localStorage' | 'cookies'
|
||||
}
|
||||
|
||||
export interface AuthState<T> {
|
||||
isLogin: boolean
|
||||
isFetchingUser: boolean
|
||||
user: T
|
||||
tokenInstance?: TokenInstance
|
||||
enum LoadingType {
|
||||
'requesting token',
|
||||
'fetching user',
|
||||
'validating token'
|
||||
}
|
||||
|
||||
export interface AuthLoadingInstance {
|
||||
isLoading: boolean
|
||||
type?: LoadingType
|
||||
}
|
||||
|
||||
export interface AuthState<T> {
|
||||
isAuthenticated: boolean
|
||||
loading: AuthLoadingInstance
|
||||
user: T
|
||||
}
|
||||
|
||||
const Context = React.createContext({})
|
||||
|
||||
@ -27,29 +38,36 @@ class AuthContextProvider extends BaseContextProvider<
|
||||
AuthState<any>
|
||||
> {
|
||||
state: AuthState<any> = {
|
||||
isLogin: false,
|
||||
isFetchingUser: false,
|
||||
isAuthenticated: false,
|
||||
loading: {
|
||||
isLoading: false
|
||||
},
|
||||
user: {
|
||||
username: ''
|
||||
}
|
||||
}
|
||||
|
||||
tokenInstance: TokenInstance | null | undefined = null
|
||||
|
||||
constructor(props: AuthContextProps) {
|
||||
super(props)
|
||||
|
||||
this.state.tokenInstance = new LocalStorageToken()
|
||||
this.tokenInstance = new LocalStorageToken()
|
||||
}
|
||||
|
||||
getContext() {
|
||||
return Context
|
||||
}
|
||||
|
||||
fetchUser: (username: string, password: string) => void = async (
|
||||
requestToken: (username: string, password: string) => void = async (
|
||||
username,
|
||||
password
|
||||
) => {
|
||||
this.setState({
|
||||
isFetchingUser: true
|
||||
loading: {
|
||||
isLoading: true,
|
||||
type: LoadingType['requesting token']
|
||||
}
|
||||
})
|
||||
const { authUrl } = this.props
|
||||
|
||||
@ -63,10 +81,12 @@ class AuthContextProvider extends BaseContextProvider<
|
||||
|
||||
const data = await response.json()
|
||||
if (response.status >= 400) {
|
||||
return Promise.reject(new ResponseError("Error while fetching data", data ))
|
||||
return Promise.reject(
|
||||
new ResponseError('Error while fetching data', data)
|
||||
)
|
||||
}
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
this.state.tokenInstance?.setToken(data.token)
|
||||
this.tokenInstance?.setToken(data.token)
|
||||
|
||||
this.setState((oldState) => {
|
||||
return {
|
||||
@ -75,12 +95,14 @@ class AuthContextProvider extends BaseContextProvider<
|
||||
...oldState.user,
|
||||
username
|
||||
},
|
||||
isLogin: true,
|
||||
isFetchingUser: false
|
||||
isAuthenticated: true,
|
||||
loading: {
|
||||
isLoading: false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return Promise.resolve("")
|
||||
return Promise.resolve('')
|
||||
}
|
||||
|
||||
login = async ({
|
||||
@ -90,22 +112,22 @@ class AuthContextProvider extends BaseContextProvider<
|
||||
username: string
|
||||
password: string
|
||||
}) => {
|
||||
return this.fetchUser(username, password)
|
||||
return this.requestToken(username, password)
|
||||
}
|
||||
|
||||
logout = async () => {
|
||||
this.setState({
|
||||
isLogin: false,
|
||||
isAuthenticated: false,
|
||||
user: {
|
||||
username: ''
|
||||
}
|
||||
})
|
||||
this.state.tokenInstance?.setToken("")
|
||||
this.tokenInstance?.setToken('')
|
||||
return Promise.resolve(true)
|
||||
}
|
||||
|
||||
getToken = ()=>{
|
||||
return this.state.tokenInstance?.getToken()
|
||||
getToken = () => {
|
||||
return this.tokenInstance?.getToken()
|
||||
}
|
||||
|
||||
getContextReturnValue() {
|
||||
@ -116,6 +138,60 @@ class AuthContextProvider extends BaseContextProvider<
|
||||
getToken: this.getToken
|
||||
}
|
||||
}
|
||||
|
||||
validateToken = async (token: string, addtionalDataForValidate: any) => {
|
||||
this.setState({
|
||||
loading: {
|
||||
isLoading: true,
|
||||
type: LoadingType['validating token']
|
||||
}
|
||||
})
|
||||
|
||||
const { validateUrl } = this.props
|
||||
const bearer = 'Bearer ' + token
|
||||
|
||||
try {
|
||||
const response = await fetch(validateUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: bearer,
|
||||
credentials: 'include'
|
||||
},
|
||||
body: JSON.stringify(addtionalDataForValidate)
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (response.status < 400 && data) {
|
||||
this.setState({
|
||||
loading: {
|
||||
isLoading: false
|
||||
},
|
||||
isAuthenticated: true
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const newToken = this.tokenInstance?.getToken()
|
||||
|
||||
if (newToken) {
|
||||
const { keysPropertyToValidate } = this.props
|
||||
let data: any = {}
|
||||
|
||||
keysPropertyToValidate?.forEach((item) => {
|
||||
data[item] = this.tokenInstance?.getAdditionalDataForTokenValidation(
|
||||
item
|
||||
)
|
||||
})
|
||||
|
||||
this.validateToken(newToken, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
|
Loading…
Reference in New Issue
Block a user