Creating a Reddit Clone Using React and GraphQL - 04
Tags: react, typescript, graphql, redditclone
Published: 2021-02-08 16:06:16

The codebase for this article that can find in here.

[**rasikag/reddit-clone**](https://github.com/rasikag/reddit-clone/tree/5_add_sessions)



Now we are going to implement the user authentication for this application. To do that we are using session authentication using cookies.

We use `Session` to do that. It will store some data on user on our server. To store data on the server, we use Redis in-memory database. It is really fast and every request we need to check that the user is logged or not.

You can install Redis using the below guide.

[**Redis Quick Start - Redis**](https://redis.io/topics/quickstart)

Then we are using `connect-redis.` All the details you can find in here.

[**tj/connect-redis**](https://github.com/tj/connect-redis)

To install, add below command.

```javascript
yarn add redis connect-redis express-session
```

`redis` is the Redis client. Then `connect-redis`is the connector for Redis client. `express-session` is our server-side session manager.

Now copy the below code from there example in `connect-redis`. Once you convert `require` you will get this error.

```javascript
could not find a declaration file for module redis
```

This means we need to add type support. To do that, add below modules.

```javascript
yarn add -D @types/redis @types/express-session @types/connect-redis
```

Now, we move this code bit inside of the main function and before the Apollo middleware. The order is a matter in here because Apollo middleware will you the Redis. So we need to initiate in before it.

```javascript

const RedisStore = connectRedis(session);
const redisClient = redis.createClient();

app.use(
  session({
    store: new RedisStore({ client: redisClient }),
    secret: "keyboard cat",
    resave: false,
  })
);
const apolloServer = new ApolloServer({
  schema: await buildSchema({
    resolvers: [HelloResolver, PostResolver, UserResolver],
    validate: false,
  }),
  context: () => ({ em: orm.em }),
});

```

Now we are adding few settings to the session object.

`disableTouch : true`

This will keep the session alive forever. unless we need to define TTL(Time to Live) and every time the user did something, the client needs to send a request that telling refresh the session time. From this, we can reduce server calls.

`name` prop.

Name of the cookie. (`qid`)

`maxAge` property in the cookie 

The maximum age for the cookie 

`httpOnly` prop in the cookie 

This prop defines that front-end JavaScript code can’t access the cookie. Good for security.

`secure` prop in the cookie 

This will only allow to create and use this cookie in `https` environment 

`sameSite` prop in the cookie

This will protect from `csrf` attacks.

`saveUninitialized` to false

If we did not add this prop, it will create a session even we didn’t add the props. We don’t need to add an empty session. To prevent that add this prop.

Now we change the `RedditContext` file to use request and response object. This makes it to use type support. Then pass it to `ApolloServer` object.

```javascript
...
context: ({ req, res }: RedditDbContext) => ({ em: orm.em, req, res }),
...
```

Okay, now we are adding session in user registration. First, add the `req` parameter in `register` resolver. 

```javascript
...
@Ctx() { em,req }: RedditDbContext
...

```

Then we can access the `session` object. We can store anything inside a `session` object. In here we only need to have `userId`.

```javascript

req.session.userId = user.id
```

But, here we will get an error saying,

```javascript
Property 'userId' does not exist on type 'Session & Partial<SessionData>'.

```

To fix that, we are adding it to `RedditContext` ‘s `request` object as below.

```javascript
req: Request  & {session: Session & Partial<SessionData> & {userId: number}};
// this & sign will join these types together
```

Okay, at this point all set up and we are going to test this. First, you need to change some setting on `GraphQL` playground setting on your localhost. In there, change `"request.credentials”: “omit”` to `“request.credentials”: “include”`. Unless this will not work.

To check the cookie, open the developer tools and select the Application section. Using login query, try to log in and once you successfully logged in you will see the cookie with name as `qid` and cookie value.

I will wrap-up this note from here. Soon I will publish the next part of this note.

If you have anything to ask regarding this please leave a comment here. Also, I wrote this according to my understanding. So if any point is wrong, don’t hesitate to correct me. I really appreciate you.

That’s for today friends. See you soon. Thank you.

References:

This article series based on the [Ben Award - Fullstack React GraphQL TypeScript Tutorial](https://www.youtube.com/watch?v=I6ypD7qv3Z8).

Main image [credit](https://www.pexels.com/photo/photography-of-person-on-green-mountain-691034/)