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