🔥node 、qwik、mongoose搞一个用户服务

avatar
前端工程师

最近小弟学习qwik中,干学不练反正是不行滴,所以花了点时间搞了个用户服务,由此来巩固知识

qwik(qwik.builder.io/)

qwik是一个全新的ssr框架,它致力于打造一个高效的ssr框架,具体这里就不展开了,大家可以下去了解

qwik的安装:
   npm install qwik -g
创建一个qwik项目
npm create qwik@latest 
pnpm create qwik@latest 
yarn create qwik <br/>

随后就创建好了一个qwik项目,其中routes文件夹是框架提供的路由服务集合,如我们在routers创建了一个login/index.tsx,则自动创建了一个 login路由。
如果我们要提供一个前端页面的话,则需要export default component$( TSX function),是一个类似react hook的dsl。
如果我们要创建一个http服务的话,则需要使用如下方式

export const onGet: RequestHandler = async (requestEvent) => {
    ...
    requestEvent.json(200, res);
};
  
export const onPost: RequestHandler = async (requestEvent) => {
    ...
    requestEvent.json(200, res);
};

export const onRequest: RequestHandler = async (requestEvent) => {
    ...
    requestEvent.json(200, res);
};
...

mongoose

mongoose 的安装

npm i mongoose --save

链接本地数据库

import mongoose from 'mongoose'
mongoose.connect('mongodb://127.0.0.1:27017/runner_blog')
    .then(() => { console.log("数据库连接成功") })
    .catch((err) => { console.log("数据库连接失败", err) })

新建一个user 用户表

const Schema = mongoose.Schema;
const UserSchema = new Schema({
    phoneNum: {
        type: String,
        required: true,
        trim: true
    },
    nickName: {
        type: String,
        required: false
    },
    password: {
        type: String,
        required: true
    },
    role: {
        type: String,
        default: 'basic',
        enum: ["basic", "supervisor", "admin"]
    },
    token: {
        type: String
    },
    create_time: {
        type: String
    }
});

const User = mongoose.model('user', UserSchema);
export default User

新建一个用户控制器(个人习惯)

import bcrypt from 'bcryptjs';
import User from '~/models/user';
import jwt from 'jsonwebtoken';
import moment from 'moment';
import objectIdToTimestamp from 'objectid-to-timestamp';


const SALT_WORK_FACTOR = 10;
const SECRET_OR_PRIVATE_KEY = "weizhonghuajuqi"
export async function hashPassword(password: string): Promise<string> {
    return await bcrypt.hash(password, SALT_WORK_FACTOR);
}
export function hashPhoneNum(phoneNum: string): string {
    return new Buffer(phoneNum, 'base64').toString()
}

export async function validatePassword(plainPassword: string, hashedPassword: string): Promise<boolean> {
    return await bcrypt.compare(plainPassword, hashedPassword);
}

export async function save(params: UserType): Promise<string> {
    const userInfo: UserType = {
        phoneNum: await hashPhoneNum(params.phoneNum),
        nickName: params.nickName,
        password: await hashPassword(params.password),
    }
    const user = new User(userInfo);
    user.token = createdToken(params.phoneNum)
    user.create_time = moment(objectIdToTimestamp(user._id)).format('YYYY-MM-DD HH:mm:ss')
    await user.save()
    return user.token
}

export async function findUserByPhoneNum(phoneNum: string) {
    try {
        return await User.findOne({ phoneNum: await hashPhoneNum(phoneNum) })
    } catch (error) {
        return false
    }
}

export async function findUserByToken(token: string) {
    try {

        return await User.findOne({ token })
    } catch (error) {
        return false
    }
}

/**
 * 登录 or 注册
 * @param params 
 * @returns 
 */
export async function login(params: UserType) {
    console.info("login", params)
    const user = await findUserByPhoneNum(params.phoneNum);
    console.info("login", user, params.phoneNum)
    if (user) {
        const valiSuccess = await validatePassword(params.password, user.password)
        if (valiSuccess) {
            user.token = createdToken(params.phoneNum)
            await user.save()
            return {
                code: 200,
                data: user.token
            }
        } else {
            return {
                code: 401,
                data: null
            }
        }
    } else {
        return {
            code: 200,
            token: await save(params)
        }
    }
}


function createdToken(phoneNum: string) {
    const token = jwt.sign({ user_id: phoneNum }, SECRET_OR_PRIVATE_KEY, {        expiresIn: '30 days' });
    return token;
}

export async function checkToken(token: string) {
    try {
        return await jwt.verify(token, SECRET_OR_PRIVATE_KEY)
    } catch (error) {
        return false
    }

}
export type UserType = {
    phoneNum: string,
    nickName?: string,
    password: string
}

qwik http 登录接口接口

import type { RequestHandler } from '@builder.io/qwik-city';
import { login } from '~/controller/auth'
export const onGet: RequestHandler = async (requestEvent) => {
    const password: string = requestEvent.query.get('password') || ''
    const phoneNum: string = requestEvent.query.get('phoneNum') || ''

    const res = await login({
        phoneNum,
        password
    })
    requestEvent.cookie.set('auth-token', res.data || '');
    requestEvent.json(200, res);
};

export const onPost: RequestHandler = async (requestEvent) => {

    requestEvent.json(200, requestEvent);
};

到这里 在qwik项目里就创建好了一个登录接口,未完持续更新~