加入我们,于10月8日至10日在纽约市,了解有关 GraphQL 联邦和 API 平台工程的最新技巧、趋势和新闻。加入我们参加 2024 年纽约市的 GraphQL 大会
文档
免费开始

身份验证


如果加载的数据并非全部公开,或者您的应用有用户、账户和权限系统,那么您需要一种方式来告诉服务器每个请求关联的用户。

使用超级灵活的Apollo Link,它包括多种认证选项。

如果您的应用基于浏览器,并且您使用 cookie 与后端进行登录和会话管理,将 cookie 随每个请求发送给网络接口。例如,传递 credentials 选项:credentials: 'same-origin' 如果您的后端服务器与下面一样位于同一域名,否则credentials: 'include' 如果您的后端位于不同域名。

const link = createHttpLink({
uri: '/graphql',
credentials: 'same-origin'
});
const client = new ApolloClient({
cache: new InMemoryCache(),
link,
});

此选项传递给HttpLink在发送查询时使用的fetch实现

注意:后端还必须允许从请求源中获取凭据。例如,如果在使用流行的npm中'req'包的node.js,以下设置将与上述Apollo客户端设置协同工作:

// enable cors
var corsOptions = {
origin: '<insert uri of front-end domain>',
credentials: true // <-- REQUIRED backend setting
};
app.use(cors(corsOptions));

使用HTTP进行身份验证的另一种常见方式是发送授权头发送。通过链式使用Apollo Links向每个HTTP请求添加一个authorization头部。在本示例中,我们将每次发送请求时从localStorage中提取登录令牌:

ReactJS示例

import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
const httpLink = createHttpLink({
uri: '/graphql',
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const token = localStorage.getItem('token');
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});

VueJS示例

import ApolloClient from "apollo-client";
import { HttpLink } from "apollo-link-http";
import { ApolloLink, concat } from "apollo-link";
import { InMemoryCache } from "apollo-cache-inmemory";
import { getMainDefinition } from "apollo-utilities";
const httpLink = new HttpLink({ uri: process.env.VUE_APP_API_TARGET });
const authMiddleware = new ApolloLink((operation, forward) => {
// add the authorization to the headers
const token = localStorage.getItem('token');
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : "",
},
});
return forward(operation);
});
export const apolloClient = new ApolloClient({
link: concat(authMiddleware, httpLink),
cache: new InMemoryCache(),
});

服务器可以使用该头部来验证用户并将其附加到GraphQL执行上下文,这样解析器就可以根据用户的角色和权限修改其行为。

退出时重置存储

由于Apollo缓存了您的所有查询结果,当登录状态改变时删除这些结果是很重要的。

最简单的方法确保UI和存储状态反映当前用户权限,是在您的登录或登出过程完成后调用client.resetStore()。这将导致存储被清除并所有活动查询将被重新取回。如果您只想清除存储而不想重新取回活动查询,则使用client.clearStore()。另一个选项是刷新页面,这将产生类似的效果。

const PROFILE_QUERY = gql`
query CurrentUserForLayout {
currentUser {
login
avatar_url
}
}
`;
function Profile() {
const { client, loading, data: { currentUser } } = useQuery(
PROFILE_QUERY,
{ fetchPolicy: "network-only" }
);
if (loading) {
return <p className="navbar-text navbar-right">Loading...</p>;
}
if (currentUser) {
return (
<span>
<p className="navbar-text navbar-right">
{currentUser.login}
&nbsp;
<button
onClick={() => {
// call your auth logout code then reset store
App.logout().then(() => client.resetStore());
}}
>
Log out
</button>
</p>
</span>
);
}
return (
<p className="navbar-text navbar-right">
<a href="/login/github">Log in with GitHub</a>
</p>
);
}
上一页
高级HTTP网络
下一页
迁移到Apollo Client 3.0
评价文章评价

©2024Apollo Graph Inc.,即Apollo GraphQL。

隐私政策

公司