angular - Angular 8 graphql.module localstorage.getItem 不可用
问题描述
使用的版本:
Angular 版本:8.3 阿波罗客户端:2.6.0
我正在尝试将 graphql 与授权的 jwt 令牌一起使用。登录后令牌在本地存储中设置。
登录时,主页会在执行 gql 查询的位置加载,但是,由于在应用程序加载时导入了 graphql.module.ts,因此令牌在加载时不可用。有没有办法修改这个模块?参考链接在这里
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { ApolloModule, Apollo, APOLLO_OPTIONS } from 'apollo-angular';
import { HttpLinkModule, HttpLink } from 'apollo-angular-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloLink } from 'apollo-link';
import { setContext } from 'apollo-link-context';
const uri = '/graphql';
export function provideApollo(httpLink: HttpLink) {
const basic = setContext((operation, context) => ({
headers: {
Accept: 'charset=utf-8'
}
}));
// Get the authentication token from local storage if it exists
const token = localStorage.getItem('token');
const auth = setContext((operation, context) => ({
headers: {
Authorization: `Bearer ${token}`
},
}));
const link = ApolloLink.from([basic, auth, httpLink.create({ uri })]);
const cache = new InMemoryCache();
return {
link,
cache
}
}
@NgModule({
exports: [
HttpClientModule,
ApolloModule,
HttpLinkModule
],
providers: [{
provide: APOLLO_OPTIONS,
useFactory: provideApollo,
deps: [HttpLink]
}]
})
export class GraphQLModule {}
解决方案
这是我对需要有效 JWT 的受保护端点进行的 graphql 调用的精简版本。显然,这个逻辑应该被放入一个服务类中,但它至少会展示你的主页应该如何与你的 graphql 模块类联系起来,并将你的 JWT 注入到请求中。
import { Component, OnInit } from '@angular/core';
import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';
@Component({
selector: 'app-user-profile',
templateUrl: './user-profile.component.html',
styleUrls: ['./user-profile.component.scss']
})
export class UserProfileComponent implements OnInit {
constructor(
private apollo: Apollo
) { }
user: any;
ngOnInit(): void {
this.apollo.query<any>({
query: gql`
query users {
loggedInUser {
email,
avatarUrl
}
}
`
}).subscribe(result => {
this.user = result.data.loggedInUser;
console.log(result);
});
}
}
这是我的 graphql 模块,它与您的非常相似,除了我还包含了刷新令牌策略。
import { NgModule } from '@angular/core';
import { HttpLinkModule, HttpLink } from 'apollo-angular-link-http';
import { AuthenticationService } from './authentication/services/authentication.service';
import { ApolloLink } from 'apollo-link';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloModule, APOLLO_OPTIONS } from 'apollo-angular';
import { onError } from 'apollo-link-error';
import { Observable } from 'apollo-link';
export function createApollo(httpLink: HttpLink, authenticationService: AuthenticationService) {
const authLink = new ApolloLink((operation, forward) => {
operation.setContext({
headers: {
Authorization: 'Bearer ' + localStorage.getItem('auth_token')
}
});
return forward(operation);
});
const errorLink = onError(({ forward, graphQLErrors, networkError, operation }) => {
if (graphQLErrors) {
if (graphQLErrors.some(x => x.message.toLowerCase() === 'unauthorized')) {
return promiseToObservable(authenticationService.refreshToken().toPromise()).flatMap(() => forward(operation));
}
}
});
return {
link: errorLink.concat(authLink.concat(httpLink.create({ uri: '/graphql' }))),
cache: new InMemoryCache(),
};
}
const promiseToObservable = (promise: Promise<any>) =>
new Observable((subscriber: any) => {
promise.then(
value => {
if (subscriber.closed) {
return;
}
subscriber.next(value);
subscriber.complete();
},
err => subscriber.error(err)
);
});
@NgModule({
exports: [ApolloModule, HttpLinkModule],
providers: [
{
provide: APOLLO_OPTIONS,
useFactory: createApollo,
deps: [HttpLink, AuthenticationService]
}
]
})
export class GraphqlModule { }
推荐阅读
- ios - 需要帮助将列表项拖动到 IOS 中的日历工具包
- javascript - 如何用相同的类但不同的位置包装所有元素
- d3.js - 如何减小 d3.js 中 svg 的大小?
- android-recyclerview - 在 Firebase RecyclerView Cardview 中单击项目时如何使用 onClickListener 打开新活动
- sql - 在 Presto 中将存储为 INT 的时间转换为 VARCHAR
- google-cloud-platform - 如何从 BigQuery 读取 google-cloud-storage 文件的元数据
- android - 推送令牌无效
- python - driver.find_elements_by_class_name 即使在 Selenium,Python 中睡眠时也会返回一个空列表
- java - 有没有办法识别 PDF 是否是 Java 中的图像 PDF?
- gcc - 无法重现构建静态库