如何将 cookie 添加到 vue-apollo 请求中?
Posted
技术标签:
【中文标题】如何将 cookie 添加到 vue-apollo 请求中?【英文标题】:How to add cookies to vue-apollo request? 【发布时间】:2020-02-22 06:11:05 【问题描述】:我使用vue-cli-plugin-apollo,我想通过cookie将用户选择的language
从前端发送到后端。
作为vue-apollo.js
,我使用下一个模板
import Vue from 'vue'
import VueApollo from 'vue-apollo'
import createApolloClient, restartWebsockets from 'vue-cli-plugin-apollo/graphql-client'
// Install the vue plugin
Vue.use(VueApollo)
// Name of the localStorage item
const AUTH_TOKEN = 'apollo-token'
// Http endpoint
const httpEndpoint = process.env.VUE_APP_GRAPHQL_HTTP || 'http://localhost:4000/graphql'
// Files URL root
export const filesRoot = process.env.VUE_APP_FILES_ROOT || httpEndpoint.substr(0, httpEndpoint.indexOf('/graphql'))
Vue.prototype.$filesRoot = filesRoot
// Config
const defaultOptions =
// You can use `https` for secure connection (recommended in production)
httpEndpoint,
// You can use `wss` for secure connection (recommended in production)
// Use `null` to disable subscriptions
wsEndpoint: process.env.VUE_APP_GRAPHQL_WS || 'ws://localhost:4000/graphql',
// LocalStorage token
tokenName: AUTH_TOKEN,
// Enable Automatic Query persisting with Apollo Engine
persisting: false,
// Use websockets for everything (no HTTP)
// You need to pass a `wsEndpoint` for this to work
websocketsOnly: false,
// Is being rendered on the server?
s-s-r: false,
// Override default apollo link
// note: don't override httpLink here, specify httpLink options in the
// httpLinkOptions property of defaultOptions.
// link: myLink
// Override default cache
// cache: myCache
// Override the way the Authorization header is set
// getAuth: (tokenName) => ...
// Additional ApolloClient options
// apollo: ...
// Client local data (see apollo-link-state)
// clientState: resolvers: ... , defaults: ...
// Call this in the Vue app file
export function createProvider (options = )
// Create apollo client
const apolloClient, wsClient = createApolloClient(
...defaultOptions,
...options,
)
apolloClient.wsClient = wsClient
// Create vue apollo provider
const apolloProvider = new VueApollo(
defaultClient: apolloClient,
defaultOptions:
$query:
// fetchPolicy: 'cache-and-network',
,
,
errorHandler (error)
// eslint-disable-next-line no-console
console.log('%cError', 'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;', error.message)
,
)
return apolloProvider
取自here。显示所有选项here。
我在不同的 github 讨论中看到 cookies
必须放在 headers
中,例如 here。然后我发现apollo-link-http
有headers 选项,所以最后我尝试了不同的变体...:
httpLinkOptions:
headers:
// Tried something like:
cookie[s]: 'language=en; path=/;'
// and something like:
cookie[s]:
language: 'en'
但没有运气。
如果是 cookieS,我会收到 Error: Network error: Failed to fetch
。
如果是cookie
,发送请求没有问题,但后端看不到language
cookie。
我使用Postman
仔细检查了后端,在这种情况下,后端接收到手动添加language
cookie 的请求。
谁能帮帮我?
【问题讨论】:
【参考方案1】:找到解决方案。
前端设置
-
创建 cookie:
export function languageCookieSet (lang)
document.cookie = `language=$lang; path=/;`
-
将
httpLinkOptions
添加到defaultOptions
的vue-apollo.js
。
const defaultOptions =
...
httpLinkOptions:
credentials: 'include'
,
...
后端设置
作为后端,我使用Django
(当前为 v2.2.7)。
-
对于开发,我们需要使用django-cors-headers
我的
development.py
现在看起来像:
from .production import *
CORS_ORIGIN_WHITELIST = (
'http://localhost:8080',
)
CORS_ALLOW_CREDENTIALS = True
INSTALLED_APPS += ['corsheaders']
MIDDLEWARE.insert(0, 'corsheaders.middleware.CorsMiddleware')
-
添加到
production.py
:
LANGUAGE_COOKIE_NAME = 'language'
LANGUAGE_COOKIE_NAME
的默认值是django_language
,所以如果适合你就改
document.cookie = `language=$lang; path=/;`
到
document.cookie = `django_language=$lang; path=/;`
-
现在我们可以在后端获取前端语言:
import graphene
from django.contrib.auth import get_user_model
from django.utils.translation import gettext as _
from .views import user_activation__create_email_confirmation
User = get_user_model()
class UserRegister(graphene.Mutation):
"""
mutation
userRegister(email: "test@domain.com", password: "TestPass")
msg
"""
msg = graphene.String()
class Arguments:
email = graphene.String(required=True)
password = graphene.String(required=True)
def mutate(self, info, email, password):
request = info.context
# Here we get either language from our cookie or from
# header's "Accept-Language" added by Browser (taken
# from its settings)
lang = request.LANGUAGE_CODE
print('lang:', lang)
if User.objects.filter(email=email).exists():
# In our case Django translates this string based
# on the cookie's value (the same as "request.LANGUAGE_CODE")
# Details: https://docs.djangoproject.com/en/2.2/topics/i18n/translation/
msg = _('Email is already taken')
else:
msg = _('Activation link has been sent to your email.')
user = User(email=email)
user.set_password(password)
user.save()
user_activation__create_email_confirmation(info.context, user)
return UserRegister(msg=msg)
注意:我尚未在生产环境中测试这些更改,但在生产环境中,我只使用一台服务器,其中前端和后端位于 nginx
后面,这就是 CORS 设置位于 @ 的原因987654338@ 而不是 production.py
。同样在生产中credentials: 'include'
可能会更改为credentials: 'same-origin'
(即更严格)。
【讨论】:
以上是关于如何将 cookie 添加到 vue-apollo 请求中?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Vuepress 站点中使用 vue-apollo?
如何从 vue-apollo 中访问 this.$route?
当我在 Vue-apollo 中使用本地状态时如何获取远程 GraphQL 数据