add validate token on component did mount

This commit is contained in:
Vut Pov 2020-07-18 11:50:25 +07:00
parent bafdfcc21b
commit 978a1cea6a
7 changed files with 108 additions and 11974 deletions

View File

@ -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

View File

@ -43,6 +43,10 @@ const FormLogin = () => {
<button type={'submit'}>Submit</button> <button type={'submit'}>Submit</button>
</form> </form>
<br /> <br />
<pre>
{JSON.stringify(auth)}
</pre>
</> </>
) )
} }

View File

@ -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"

View File

@ -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",

View File

@ -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 }

View File

@ -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

11947
yarn.lock

File diff suppressed because it is too large Load Diff