123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- 'use strict';
- /**
- * 登录日志-数据模型
- *
- * @author lanjianrong
- * @date 2020/8/31
- * @version
- */
- const UAParser = require('ua-parser-js');
- module.exports = app => {
- class LoginLogging extends app.BaseService {
- constructor(ctx) {
- super(ctx);
- this.tableName = 'login_logging';
- }
- /**
- * 创建记录
- * @param {Object} payload - 载荷
- */
- async createLog(payload) {
- const transaction = await this.db.beginTransaction();
- try {
- transaction.insert(this.tableName, payload);
- await transaction.commit();
- } catch (error) {
- await transaction.rollback();
- throw error;
- }
- }
- /**
- * 创建登录日志
- * @return {Boolean} 日志是否创建成功
- */
- async addLoginLog() {
- const { ctx } = this;
- const ip = ctx.header['x-real-ip'] ? ctx.header['x-real-ip'] : '';
- const ipInfo = await this.getIpInfoFromApi(ip);
- const parser = new UAParser(ctx.header['user-agent']);
- const osInfo = parser.getOS();
- const cpuInfo = parser.getCPU();
- const browserInfo = parser.getBrowser();
- const payload = {
- os: `${osInfo.name} ${osInfo.version} ${cpuInfo.architecture}`,
- browser: `${browserInfo.name} ${browserInfo.version}`,
- ip,
- address: ipInfo,
- uid: ctx.session.sessionUser.accountId,
- pid: ctx.session.sessionProject.id,
- };
- return await this.createLog(payload);
- }
- /**
- * 根据ip请求获取详细地址
- * @param {String} a_ip - ip地址
- * @return {String} 详细地址
- */
- async getIpInfoFromApi(a_ip = '') {
- if (!a_ip) return '';
- if (a_ip === '127.0.0.1') return '服务器本机访问';
- const { ip = '', region = '', city = '', isp = '' } = await this.sendRequest(a_ip);
- let address = '';
- region && (address += region + '省');
- city && (address += city + '市 ');
- isp && (address += isp + ' ');
- ip && (address += `(${ip})`);
- return address;
- }
- /**
- * 发送请求获取详细地址
- * @param {String} ip - ip地址
- * @param {Number} max - 最大重试次数
- * @return {Object} the result of request
- * @private
- */
- async sendRequest(ip, max = 3) {
- return new Promise(resolve => {
- const start = () => {
- if (max <= 0) {
- resolve(); // 已达到最大重试次数,返回空的执行承若
- }
- max--;
- this.ctx.curl(`https://api01.aliyun.venuscn.com/ip?ip=${ip}`, {
- dateType: 'json',
- encoding: 'utf8',
- timeout: 2000,
- headers: {
- Authorization: 'APPCODE 85c64bffe70445c4af9df7ae31c7bfcc',
- },
- }).then(({ status, data }) => {
- if (status === 200) {
- const result = JSON.parse(data.toString()).data;
- if (!result.ip) {
- start();
- } else {
- max++;
- resolve(result);
- }
- } else {
- max--;
- start();
- }
- }).catch(() => {
- start();
- });
- };
- start();
- });
- }
- /**
- * 获取登录日志
- * @param {Number} pid - 项目id
- * @param {Number} uid - 用户id
- * @return {Promise<Array>} 日志数组
- */
- async getLoginLogs(pid, uid) {
- return this.db.select(this.tableName, {
- where: { pid, uid },
- orders: [['create_time', 'desc']],
- columns: ['browser', 'create_time', 'ip', 'os', 'address'],
- limit: 10, offset: 0,
- });
- }
- }
- return LoginLogging;
- };
|