问题
I am using React as frontend and REST API as backend, my REST is issuing http only Cookie what i am storing on frontend and using on every REST request, for example of code, Atlassian JIRA have auth like that , now i want to migrate that solution from REST to GraphQL, and if authorisation on GraphQL side is already solved problem (only Apollo have both Cookie and JWT auth mechanisms, not to mention native implementations), i still can't figure out how to issue Cookie/JWT from GraphQL side.
Is there possibility to provide me cookie from GraphQL at all? Question is how GraphQL can set new cookie on client? Is something like set-cookie header possible?
回答1:
If you want to avoid having a separate authentication endpoint and instead want to be able to send a mutation to your GraphQL endpoint and have that generate the authorization cookie, you'll need to modify how you set up your GraphQL endpoint on the server.
When using express-graphql
or apollo-server-express
, your request object is passed to your resolvers as the context by default. In order to get your response object, you have to wrap your endpoint like this:
app.use('/graphql', (req, res) => {
return graphqlHTTP({
schema,
context: { req, res },
})(req, res);
);
Within the resolver for that mutation, you can then set the cookie using res.cookie()
.
Handling things this way can be a pain, though -- you may want to utilize one or more separate endpoints for authentication, which would allow you to utilize libraries like passport
to do the heavy lifting.
回答2:
For passing a pre-existing token into a GraphQL query or mutation, you only need to assign the token to the variables
object inside your query/mutation.
Here is an example using Apollo's graphql
Higher Order Component, and extracting a token from the Redux Store. Here I'm destructuring a queryParams
branch that works with the library react-router-redux
to automatically extract and save any query params on the active url, to the redux store.
const FetchTrackingInfo = gql`
query FetchTrackingInfo($token: String!) { // create a $token variable reference and declare the Scalar type.
FetchTrackingInfo(token: $token) { // assign a token parameter to the variable $token
error {
hard
soft
message
}
shipDate
orderId
trackingNumber
trackingInfo {
location
date
activity
}
}
}
`;
const OrderTrackingWithData = graphql(
FetchTrackingInfo, {
name: 'TrackingInfo',
options: ({ queryParams }) => { // destructuring queryParams from the redux store.
const token = queryParams.token ? queryParams.token : '';
return ({
variables: { token }, // assign token to the variables of the query/mutation.
});
},
},
)(OrderTracking); // Pass in your React component to the HOC: graphql
Now, if you mean you're trying to CREATE a JWT token from the Client when you say "how to issue Cookie/JWT from Graphql side", then this is a potential security flaw in your app. JWT's require a Secret
at the time of signing/creating the token. Typically this is made available via environment variables for security reasons. A client side browser exposes all environment variables publicly. Which means, creating/issuing new JWT tokens via Client side is at best, a bad practice, and at worst a huge security flaw.
来源:https://stackoverflow.com/questions/46023367/graphql-issuing-jwt-cookie