jwt跨域身份验证
In this tutorial I’ll explain how to handle a login mechanism for a GraphQL API using Apollo.
在本教程中,我将解释如何使用Apollo处理GraphQL API的登录机制。
We’ll create a private area that depending on your user login will display different information.
我们将创建一个私人区域,该区域将根据您的用户登录名显示不同的信息。
In detail, these are the steps:
详细来说,这些步骤是:
- Create a login form on the client 在客户端上创建登录表单
- Send the login data to the server 将登录数据发送到服务器
- Authenticate the user and send a JWT back 验证用户身份并将JWT发送回
Store the JWT in a cookie
将JWT存储在cookie中
- Use the JWT for further requests to the GraphQL API 将JWT用于对GraphQL API的进一步请求
The code for this tutorial is available on GitHub at https://github.com/flaviocopes/apollo-graphql-client-server-authentication-jwt
本教程的代码可在GitHub上找到, 网址为https://github.com/flaviocopes/apollo-graphql-client-server-authentication-jwt
Let’s start.
开始吧。
我启动客户端应用程序 (I start up the client application)
Let’s create the client side part using create-react-app
, run npx create-react-app client
in an empty folder.
让我们使用create-react-app
创建客户端部分,在一个空文件夹中运行npx create-react-app client
。
Then call cd client
and npm install
all the things we’ll need so that we don’t need to go back later:
然后调用cd client
,然后npm install
我们需要的所有东西,这样我们以后就不必再回去了:
npm install apollo-client apollo-boost apollo-link-http apollo-cache-inmemory react-apollo apollo-link-context @reach/router js-cookie graphql-tag
登录表格 (The login form)
Let’s start by creating the login form.
让我们从创建登录表单开始。
Create a Form.js
file in the src
folder, and add this content into it:
在src
文件夹中创建一个Form.js
文件,并将以下内容添加到其中:
import React, { useState } from 'react'
import { navigate } from '@reach/router'
const url = 'http://localhost:3000/login'
const Form = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const submitForm = event => {
event.preventDefault()
const options = {
method: 'post',
headers: {
'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
body: `email=${email}&password=${password}`
}
fetch(url, options)
.then(response => {
if (!response.ok) {
if (response.status === 404) {
alert('Email not found, please retry')
}
if (response.status === 401) {
alert('Email and password do not match, please retry')
}
}
return response
})
.then(response => response.json())
.then(data => {
if (data.success) {
document.cookie = 'token=' + data.token
navigate('/private-area')
}
})
}
return (
<div>
<form onSubmit={submitForm}>
<p>Email: <input type="text" onChange={event => setEmail(event.target.value)} /></p>
<p>Password: <input type="password" onChange={event => setPassword(event.target.value)} /></p>
<p><button type="submit">Login</button></p>
</form>
</div>
)
}
export default Form
Here I assume the server will run on localhost
, on the HTTP protocol, on port 3000
.
在这里,我假设服务器将在HTTP协议的端口3000
上的localhost
上运行。
I use React Hooks, and the Reach Router. There’s no Apollo code here. Just a form and some code to register a new cookie when we get successfully authenticated.
我使用React Hooks和Reach Router 。 这里没有阿波罗代码。 当我们成功通过身份验证时,只需一个表格和一些代码即可注册一个新的cookie。
Using the Fetch API, when the form is sent by the user I contact the server on the /login
REST endpoint with a POST request.
使用Fetch API,当用户发送表单时,我通过POST请求与/login
REST端点上的服务器联系。
When the server will confirm we are logged in, it will store the JWT token into a cookie, and it will navigate to the /private-area
URL, which we haven’t built yet.
当服务器确认我们已登录时,它将把JWT令牌存储到cookie中,并将导航到/private-area
URL(我们尚未构建)。
将表单添加到应用程序 (Add the form to the app)
Let’s edit the index.js
file of the app to use this component:
让我们编辑应用程序的index.js
文件以使用此组件: