peterlits zo
Posted on February 23, 2022
Hello, feel free to email me PETERLITSZO at GMAIL dot COM if you want to discuss with me!
RESTful API
In RESTful API, if we want to get the authentication, we can just request by POST
method, with the JSON data that about username (or email) and password, and then get the session id, or token, or JWT, etc. (See How to authentication to get more infomations)
GraphQL
Now we want to do the same thing in GraphQL:
query LogIn($email: String!, $password: String!) {
# Input the email, password, and then output the jwt.
user(email: $email, password: $password) {
jwt
}
}
UPDATED: This is question. We know that the RESTful method
GET
will never change the data but only return the data (but you can if you really want).And GraphQL
query
is same asGET
. But this time we ask server build a JWT for us, and set the cookie... It looks like not only just return a data.So if I use
mutation
, will it be a better idea?
We set the string LOG_IN_QUERY
as the graphql statement above.
To query with graphql after we click the log in button, we need to use hook useLazyQuery
(click to get more infomations) to get the function to query.
The first part is to import those hooks and function and set const string:
import { useState } from 'react';
import { useLazyQuery, gql } from '@apollo/client';
const LOG_IN_QUERY = gql`
query LogIn($email: String!, $password: String!) {
# Input email, and password, then output the jwt.
user(email: $email, password: $password) {
jwt
}
}
`;
Then we need a component to handle the login:
// React function component, export to be used in other
// JavaScript files.
export default () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [login, { loading, error, data }]
= useLazyQuery(LOG_IN_QUERY);
// If we call login, the boolean value, that loading,
// error, and data turn into, will be false.
//
// So there is other logic to deal with error, loading,
// and data.
return (
<div>
{/* Input box to input email */}
<input
value={email}
onChange={(event) => setEmail(event.target.value)}
/>
{/* Input box to input password */}
<input
value={password}
onChange={(event) => setPassword(event.target.value)}
/>
{/* Button to log in */}
<button
onClick={
() => login({ variables: { email, password } })
}
>
Log in
</button>
</div>
);
}
Well, that is all.
GraphQL with HttpOnly
cookie
Let the JavaScript can touch the cookie is danger. We can let the server give us a response with Set-Cookie
with HttpOnly
flag! It will be safe to avoid JavaScript to deal with cookie!
Now we need change the GraphQL statement, and let the server return response with Set-Cookie: jwt=<THE JWT SERVER RETURN>; HttpOnly
:
query LogIn($email: String!, $password: String!) {
# Input the email, password, and then output the jwt.
user(email: $email, password: $password) {
# Do you have a better idea than use underscore?
# If I remove all content, it will raise an error.
_
}
}
We use cookie to get the authentication, so we will use js-cookie
to get if we already have the jwt
cookie or not.
import Cookie from 'js-cookie';
import { useEffect } from 'react';
import { useNavigate } from 'react-router';
If we already signed in, we will return the previous page:
// ...
const navigator = useNavigate();
useEffect(() => {
if (Cookie.get('jwt')) {
navigator(-1); // go back
}
});
// ...
See here to get more information: Deal with HttpOnly
cookies.
Others
Here is some link to get more information, Please read those! Those are really awesome!!!:
Apollo link context, a way to set HTTP header to set the authorization.
Apollo authorization. The way to get authorization with apollo.
How to authenticate using GraphQL Cookies and JWT(Key words: A runable JavaScript GraphQL server, A client that store JWT in cookie. By the way, remember some package HAS BEEN DEPRECATED, for example,
apollo-link-context
,@apollo/link-context
and so on. Be sure read the README.md of those projects).
Posted on February 23, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.