Skip to content

Commit

Permalink
update readme, fix bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
vdfor committed Mar 21, 2018
1 parent 999cc1a commit 6b08b88
Show file tree
Hide file tree
Showing 14 changed files with 87 additions and 65 deletions.
26 changes: 21 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
[README English Version](README.en.md)

## 关于
[koa](https://github.com/koajs/koa)(2.x)的种子工程, 采用`typescript`编写

项目最初由[koa-generator](https://github.com/17koa/koa-generator)生成,最初采用`js`编写,`0.4`之后切换到`typescript`。随着项目的发展,已与最初相差甚大。
基于[koa](https://github.com/koajs/koa)(2.x)框架的种子工程, 采用`typescript`编写

## 快速开始
```bash
Expand All @@ -14,13 +12,28 @@ npm i
npm start
```

## 测试与检查
```bash
# 单元测试 first run `npm start`
npm run test
# 代码规范检查
npm run lint:check
```

## 构建

提供两种构建方式,一种使用`tsc`打包构建,一种使用[webpack](https://webpack.github.io/)打包。
提供两种构建方式:

1. 使用`tsc`打包构建

```bash
# build by tsc
npm run build
```

2. 使用[webpack](https://webpack.github.io)打包构建。

```bash
# build by webpack
npm run build:webpack
```
Expand All @@ -37,6 +50,9 @@ npm run prod
## 搭配docker
```bash
# first run `npm run build` or `npm run build:webpack`
# build docker image
# 生成docker镜像
docker build -t <image-name>:<tag> .
```

## 致谢
项目最初由[koa-generator](https://github.com/17koa/koa-generator)生成,最初采用`js`编写,`0.4`之后切换到`typescript`。虽然随着项目的发展,已与最初相差甚大,但`koa-generator`对于项目的起步十分重要。
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "koa-sail-ts",
"version": "0.6.2",
"version": "0.6.3",
"author": "vdfor",
"license": "MIT",
"repository": {
Expand All @@ -18,6 +18,7 @@
"build:webpack": "npm run clean && webpack --config webpack.config.js --progress --color",
"prod": "NODE_ENV=production pm2 start --name koaSail ./build/index.js",
"prod_docker": "NODE_ENV=production node ./build/index.js",
"lint:check": "tslint -p tsconfig.json -c tslint.json ./src/**/*.ts",
"test": "mocha --recursive",
"clean": "rm -rf build"
},
Expand Down
4 changes: 1 addition & 3 deletions src/api/login.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import * as Router from 'koa-router';
import * as Koa from 'koa';
import { signToken } from '../lib/utils';
import passport from '../lib/passport';
// const cache = require('../common/cache');

const router = new Router();

Expand All @@ -26,7 +24,7 @@ router.post('/', (ctx, next) => passport.authenticate(
}
resData = {
user,
token
access_token: token
};
}
ctx.body = resData || {};
Expand Down
16 changes: 0 additions & 16 deletions src/api/test.ts

This file was deleted.

16 changes: 16 additions & 0 deletions src/api/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as Router from 'koa-router';

const router = new Router();

router.prefix('/api/v0/user');

router.get('/:id', async (ctx) => {
const { id } = ctx.params;
ctx.body = {
id,
name: 'John',
age: Math.floor(Math.random() * 100)
};
});

export default router;
5 changes: 3 additions & 2 deletions src/api/users.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import * as Router from 'koa-router';
import * as fs from 'fs';
import auth from '../lib/auth';

const router = new Router();

router.prefix('/api/v0/users');

router.get('/', async (ctx) => {
router.get('/', auth, async (ctx) => {
console.log((ctx.request as any).uid);
ctx.body = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Lucy' }
Expand Down
4 changes: 2 additions & 2 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import onerror = require('koa-onerror');
import getLogger from './lib/logger';
// apis
import usersApi from './api/users';
import testApi from './api/test';
import userApi from './api/user';
import loginApi from './api/login';

// app
Expand Down Expand Up @@ -69,7 +69,7 @@ app.use(async (ctx, next) => {

// apis
app.use(usersApi.routes());
app.use(testApi.routes());
app.use(userApi.routes());
app.use(loginApi.routes());

// /admin /downloads => The back-end route to deal
Expand Down
29 changes: 20 additions & 9 deletions src/lib/auth.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import * as Koa from 'koa';
import { decodeToken } from './utils';
import { decodeToken, getToken } from './utils';

interface User {
id: string | number;
}

const auth = async (ctx: Koa.Context, next: Function) => {
try {
// get token from ctx.request, decode token and compare with token in cache => get userid
const uid = await decodeToken(ctx.request);
if (uid) {
// get token from ctx.request
const token = getToken(ctx.request);
if (token) {
try {
// decode token and compare with token in cache => get userid
const user = await decodeToken(token);
const { id: uid } = user as User;
(ctx.request as any).uid = uid;
await next();
return;
// const cacheToken = cache.get(`user-${uid}-token`);
// if (!cacheToken) {
// ctx.throw(401, 'unauthorized');
// }
} catch (error) {
ctx.throw(401, 'unauthorized');
}
} catch (error) {
} else {
ctx.throw(401, 'unauthorized');
}
ctx.throw(401, 'unauthorized');
await next();
};

export default auth;
1 change: 1 addition & 0 deletions src/lib/fetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// connect db and get data
15 changes: 2 additions & 13 deletions src/lib/passport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,15 @@ import * as passport from 'koa-passport';
import { Strategy as LocalStrategy } from 'passport-local';
import { hashPasswd } from './utils';

// // 序列化ctx.login()触发
// passport.serializeUser((user, done) => {
// // console.log('serializeUser: ', user);
// done(null, user);
// });
// // 反序列化(请求时,session中存在"passport":{"user":"1"}触发)
// passport.deserializeUser(async (id, done) => {
// console.log('deserializeUser: ', id)
// var user = {id: 1, username: 'admin', password: '123456'}
// done(null, user)
// })
// 提交数据(策略)
// submit data(strategy)
passport.use(new LocalStrategy(
{
usernameField: 'username',
passwordField: 'password'
},
(async (username, passwd, done) => {
// get user info from db
let dbUser = {
const dbUser = {
id: 'testid',
username: 'testname',
passwd: 'testpasswd'
Expand Down
18 changes: 9 additions & 9 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@ import config from './config';

export const hashPasswd = (passwd: string) => crypto.createHash('sha256').update(passwd).digest('base64');

export const decodeToken = (req: Koa.Request) => new Promise((resolve, reject) => {
// get token
let token;
export const getToken = (req: Koa.Request) => {
if (req && req.body && req.body.access_token) {
token = req.body.access_token;
return req.body.access_token;
} else if (req && req.query && req.query.access_token) {
token = req.query.access_token;
return req.query.access_token;
} else if (req && req.headers.authorization) {
token = req.headers.authorization.split(' ')[1];
} else {
return reject(new Error('Not access_token found'));
return req.headers.authorization.split(' ')[1];
} else { // Not access_token found
return null;
}
};

export const decodeToken = (token: string) => new Promise((resolve, reject) => {
// decode token
try {
const decoded: any = jwt.verify(token, config.jwtSecret, { ignoreNotBefore: false });
if (typeof decoded === 'object' && decoded.user && decoded.user.id) {
// const cacheToken = cache.get(`user-${decoded.user.id}-${token}`);
// return cacheToken ? decoded.user.id : null;
return resolve(decoded.user.id);
return resolve(decoded.user);
}
reject(new Error('No uid payload in access_token'));
} catch (error) {
Expand Down
8 changes: 4 additions & 4 deletions test/users.spec.js → test/user.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ const axios = require('axios');

axios.defaults.baseURL = 'http://localhost:3000';

describe('users test', () => {
it('users/', (done) => {
axios.get('/api/v0/users').then(res => {
describe('user test', () => {
it('user/', (done) => {
axios.get('/api/v0/user/1').then(res => {
assert.deepStrictEqual(200, res.status);
assert.deepStrictEqual(true, res.data instanceof Array);
assert.deepStrictEqual(true, res.data instanceof Object);
done();
});
});
Expand Down
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"moduleResolution": "node",
"esModuleInterop": false,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"noUnusedLocals": true,
"noUnusedParameters": true
},
"include": [
"./src/**/*"
Expand Down
3 changes: 3 additions & 0 deletions tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,17 @@
"no-switch-case-fall-through": true,
"no-trailing-whitespace": false,
"no-unused-expression": true,
"no-unused-variable": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"one-line": [
true,
"check-catch",
"check-else",
"check-open-brace",
"check-whitespace"
],
"prefer-const": true,
"quotemark": [
true,
"single",
Expand Down

0 comments on commit 6b08b88

Please sign in to comment.