Как использовать конечные точки Next.JS Rest, защищенные с помощью Amplify, из приложения React Native
Фон:
Мой текущий стек — это сервер Next для использования в качестве портала администрирования и REST API для мобильного приложения, работающего с Expo — React Native. Следующий сервер в настоящее время размещен как [email protected]
Я защитил сервер Next и приложение React Native с помощью оболочки withAuthenticator от AWS Amplify. (Я также пробовал определенные пакеты аутентификации, такие как пакет аутентификации Next-Auth и Expo)
Проблема:
Однако я не могу понять, как добавить информацию об аутентификации (Access_token) в мои запросы REST из мобильного приложения -> Следующий сервер
Я безуспешно пытался добавить токены в качестве заголовков носителя в API, после чего был уверен, что все это должно быть настроено и отправлено через файлы cookie. НО я застрял в том, как правильно реализовать эти файлы cookie. Я надеялся, что конечные точки:[] config можно будет использовать для настройки моего собственного домена для публикации и обработки файлов cookie. Чтение запроса на сервере показало, что он не содержал информации об аутентификации при отправке с помощью этого метода.
Аналогичным образом, используя RTK Query (предпочтительно я добавляю к этому всю аутентификацию вместо настройки API Amplify). У меня нет правильной информации для отправки авторизованного запроса API.
Вот несколько фрагментов рабочей страницы Аутентификация для обоих приложений.
Конечная точка API /api/версия:
import type { NextApiRequest, NextApiResponse } from 'next'
import { withSSRContext } from 'aws-amplify'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<Data | Error>,
) {
const { Auth } = withSSRContext({req})
try {
const user = await Auth.currentAuthenticatedUser()
return res.status(200).json({
version: '1.0.0',
user: user.username,
})
} catch (err) {
console.log(err)
return res.status(200).json({
message: 'Unauthenticated',
})
}
}
Конфигурация мобильного приложения:
import {
useAuthenticator,
withAuthenticator,
} from '@aws-amplify/ui-react-native'
import { Amplify, Auth } from 'aws-amplify'
import awsconfig from './aws-exports'
Amplify.configure({
...awsconfig,
API: {
endpoints: [
{
name: 'MyApi',
endpoint: 'http://NextIP:NextPort/api/',
},
],
},
})
Auth.configure(awsconfig)
export default withAuthenticator(App)
Мобильный экран:
import { API } from 'aws-amplify'
function getData() {
const apiName = 'MyApi'
const path = '/version'
const myInit = {
headers: {}, // OPTIONAL
}
return API.get(apiName, path, myInit)
}
export default function ModalScreen() {
// Get token / Cookie for auth
// const { data, isLoading, error } = useGetApiVersionQuery(null) // RTK Query
getData() // Amplify
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error.response)
})
return ( <></>)}
1 ответ
Я нашел решение, однако не смог заставить промежуточное ПО Next-Auth срабатывать, когда токен был отправлен с использованием токена Bearer в заголовках. Это мой идеальный способ обработки маршрутов.
Я обернул вызов getToken({req}) так, чтобы, если нет веб-токена JWT, он попытался закодировать токен отдельно. aws-amplify/auth, в моем случае из react-native.
компоненты/утилиты/auth.utils.ts
import { NextApiRequest } from 'next'
import { CognitoJwtVerifier } from 'aws-jwt-verify'
import { getToken } from 'next-auth/jwt'
// Verifier that expects valid token:
const verifier = CognitoJwtVerifier.create({
userPoolId: process.env.COGNITO_USERPOOL_ID ?? '',
tokenUse: 'id',
clientId: process.env.COGNITO_CLIENT_ID ?? '',
issuer: process.env.COGNITO_ISSUER ?? '',
})
export async function getMobileToken(req: NextApiRequest) {
let token = null
try {
token = await getToken({ req })
} catch (error) {
console.log('Could not get JWT Web Token')
}
try {
if (!token)
token = await getToken({
req,
async decode({ token }) {
if (!token) return null
const decoded = await verifier.verify(token)
return decoded
},
})
} catch (error) {
return null
}
console.log('Mobile Token:', token)
return token
}