Job Announcement Website: Authenticate User
Tags: javascript, webdev, react, opine
Published: 2022-08-13 04:55:00

{% embed https://dev.to/sokhavuth/table-of-contents-2o4e %}
GitHub: [https://github.com/Sokhavuth/opine-job](https://github.com/Sokhavuth/opine-job)
Deno Deploy: [https://khmerweb-job.deno.dev/users](https://khmerweb-job.deno.dev/users)
<br/>
<p>In Opine web framework, we can use many HTTP methods with different handlers for one route. For example, for the predefined route “/users”, we can use HTTP request method GET and POST with different handlers to get different result. In fact, we use HTTP GET method to display login form on the browser, and we are going to use HTTP POST method to check in MongoDB database to see if the user who has been submitting the login form is registered or not. If he/she is registered, we will save his/her user data in Redis database, and let him/her log into the upcoming dashboard, otherwise, we will ask him/her to resubmit the login form again with the right email and password.</p>

<p>Moreover, for the HTTP GET method, instead of sending straight the login form for the user to sign in, we are going to check in Redis database using application session to see whether his/her user data is registered or not. If his/her user data is registered, it means that he/she was already authenticated, and we will let him/her get into the dashboard without filling the login form.</p>

```js
// routes/users/login.js

import { Router } from "../../deps.ts";
const router = Router();


import login from "../../controllers/users/login.js";

router.get("/", async (req, res) => {
    if(await req.mysession.get("user")){
        res.redirect("/users/post");
    }else{ 
        login.getForm(req, res);
    }
});

router.post("/", (req, res) => {
    login.checkUser(req, res);
});



export default router;
```

```js
// controllers/users/login.js
 
import { bcrypt } from "../../deps.ts";
import login from "../../views/users/login.jsx";
import userdb from "../../models/user.ts";
 
 
class Login{
    async getForm(req, res){
        const config = req.mysetting();
        config.page_title = "Login Page";
        config.route = '/users/login';
 
        const html = await login(config);
        res.send(html);
    }
 
    async checkUser(req,res){
        const config = await req.mysetting();
        config.page_title = 'Login Page';
    
        const user = await userdb.checkUser(req);
        
        if(user){
            if(user.role in {'Admin':1,'Editor':1,'Author':1,"Guest":1}){
                if(await bcrypt.compareSync(req.body.password, user.password)){
                    await req.mysession.set("user", user);
                    res.redirect('/users/post');
                }else{
                    config.message = 'The password is wrong';
                    config.route = '/users';
    
                    const html = await login(config);
                    res.send(html);
                }
            }else if(user.role in {'Subscriber':1}){
                config.message = 'You are not registered yet';
                config.route = '/users';
    
                const html = await login(config);
                res.send(html);
            }else{
                config.message = 'You are not registered yet';
                config.route = '/users';
    
                const html = await login(config);
                res.send(html);
            }
        }else{
            config.message = 'The email is wrong';
            config.route = '/users';
    
            const html = await login(config);
            res.send(html);
        }
    }
}
 
 
export default new Login();
```

```ts
// models/users.ts
 
import { bcrypt } from '../deps.ts';
 
 
interface UserSchema {
    _id: ObjectId;
    id: string; 
    title: string;
    content: string;
    thumb: string;
    date: string;
    role: string;
    email: string;
    password: string;
}
 
class User{
    async createRootUser(req){
        const id = Date.now() + Math.round(Math.random() * 1E9).toString();
        const salt = await bcrypt.genSalt(8);
        const hashPassword = bcrypt.hashSync('xxxxxxxxxxx', salt);
 
        let newUser = {
            id: id, 
            title: 'Guest',
            content: '',
            thumb: '',
            date: '',
            role: 'Guest',
            email: 'guest@khmerweb.app',
            password: hashPassword,
        }
 
        const users = req.mydb.collection<UserSchema>("users");
        await users.insertOne(newUser);
    }
 
    async checkUser(req){
        const query = {email:req.body.email}
        const users = req.mydb.collection<UserSchema>("users");
        return await users.findOne(query);
    }
}
 
 
export default new User();
```