【发布时间】:2019-11-21 01:22:12
【问题描述】:
我正在 react-native/apollo-hooks/graphql 上使用两个令牌(accessToken、refreshToken)进行身份验证流程。并为 updateTokens 创建了 apollo-hook。这个钩子我需要在不同的组件中使用,因为每次用户想要做任何动作,比如发帖或评论时,我都需要调用 updateTokens apollo 钩子。因此我需要将 updateTokens 的所有逻辑放到一个单独的工具中,因为我不想重复自己并将相同的代码放在任何地方。但是当我用 apollo 钩子制作单独的 util 文件时,它不起作用。谁能解释一下我该怎么做!
import React from 'react'
import { View, Button, Text } from 'react-native'
import { useMutation } from 'react-apollo-hooks'
import gql from 'graphql-tag'
import * as Keychain from 'react-native-keychain'
const UPDATE_TOKENS = gql`
mutation UpdateTokens($accessToken: String!, $refreshToken: String!) {
updateTokens(data: { accessToken: $accessToken, refreshToken: $refreshToken }) {
user {
name
phone
}
accessToken
refreshToken
}
}
`
const HomeScreen = ({ navigation }) => {
const update_tokens = useMutation(UPDATE_TOKENS)
const updateTokens = (accessToken, refreshToken) => {
console.log('accessToken', accessToken)
console.log('refreshToken', refreshToken)
update_tokens({
variables: { accessToken, refreshToken },
update: async (cache, { data }) => {
const accessToken = data.updateTokens.accessToken
const refreshToken = data.updateTokens.refreshToken
await Keychain.setGenericPassword(accessToken, refreshToken)
}
}).then(() => console.log('We have new credentials'))
}
const getCredentials = async () => {
const tokens = await Keychain.getGenericPassword()
console.log('tokens', tokens)
const keyChainAccessToken = tokens.username
const keyChainRefreshToken = tokens.password
console.log('keyChainAccessToken', keyChainAccessToken)
console.log('keyChainRefreshToken', keyChainRefreshToken)
updateTokens(keyChainAccessToken, keyChainRefreshToken)
}
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button title="updateTokens" onPress={getCredentials} />
<Button title="getCredentials" onPress={checkCredentials} />
<Button title="SignOut" onPress={userSignOut} />
</View>
)
}
export { HomeScreen }
我可以像这样把它放到单独的文件中,然后在不同的地方使用它:
import { useMutation } from 'react-apollo-hooks'
import gql from 'graphql-tag'
import * as Keychain from 'react-native-keychain'
import jwtDecode from 'jwt-decode'
const UPDATE_TOKENS = gql`
mutation UpdateTokens($refreshToken: String!, $refreshTokenId: String!) {
updateTokens(refreshToken: $refreshToken, refreshTokenId: $refreshTokenId) {
user {
name
phone
}
accessToken
refreshToken
}
}
`
const updateCredentials = () => {
const update_tokens = useMutation(UPDATE_TOKENS)
const updateTokens = (refreshToken, refreshTokenId) => {
console.log('refreshToken', refreshToken)
console.log('refreshTokenId', refreshTokenId)
update_tokens({
variables: { refreshToken, refreshTokenId },
update: async (cache, { data }) => {
const newAccessToken = data.updateTokens.accessToken
const newRefreshToken = data.updateTokens.refreshToken
const user = data.updateTokens.user
await Keychain.setGenericPassword(newAccessToken, newRefreshToken)
}
}).then(() => console.log('We have new credentials'))
}
const getCredentials = async () => {
try {
const tokens = await Keychain.getGenericPassword()
console.log('tokens', tokens)
const keychainAccessToken = tokens.username
const keychainRefreshToken = tokens.password
const currentTime = Date.now() / 1000
const decodeAccessToken = jwtDecode(keychainAccessToken)
console.log('decodeAccessToken', decodeAccessToken)
const keychainRefreshTokenId = decodeAccessToken.refreshTokenId
console.log('keychainRefreshTokenId', keychainRefreshTokenId)
if (decodeAccessToken.exp > currentTime) {
console.log('Credentials is still valid')
} else if (decodeAccessToken.exp < currentTime) {
console.log('Go to Update!')
updateTokens(keychainRefreshToken, keychainRefreshTokenId)
}
} catch (err) {
throw new Error('Invalid credentials')
}
}
}
export { updateCredentials }
【问题讨论】:
标签: react-native graphql apollo