From 9db546db5cc827f03f76000aa356b4b4d3def7a2 Mon Sep 17 00:00:00 2001 From: brian lee Date: Thu, 30 Dec 2021 14:57:39 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nuxt/modules/components/post-form.vue | 21 ++++++++++++++-- nuxt/modules/pages/archive/index.vue | 21 +++++++++++++--- nuxt/modules/pages/chain/index.vue | 23 ++++++++++++++---- nuxt/modules/pages/index.vue | 23 ++++++++++++++---- .../src/middleware/blacklist.middleware.ts | 24 ++++++++++--------- .../src/modules/comment/comment.controller.ts | 8 +++---- .../src/modules/comment/comment.service.ts | 10 +++++--- 7 files changed, 99 insertions(+), 31 deletions(-) diff --git a/nuxt/modules/components/post-form.vue b/nuxt/modules/components/post-form.vue index b5bae6d..ce1f4e7 100644 --- a/nuxt/modules/components/post-form.vue +++ b/nuxt/modules/components/post-form.vue @@ -149,13 +149,17 @@ export default { { validator: validateCaptcha, trigger: 'blur', required: true } ] }, - comment_status: 1 + comment_status: 1, + comment_record_ip: 0, + headerConfigs: {} } }, async fetch () { await this.getGeetestCaptcha(); // 评论开启状态 await this.getCommentStatus(); + // 根据记录IP状态决定是否调用获取IP地址 + this.comment_record_ip && await this.getIpLocation(); }, methods: { async getCommentStatus () { @@ -164,6 +168,19 @@ export default { this.placeholder = { username: '', email: '', content: '评论已关闭' }; } this.comment_status = data.comment_status; + this.comment_record_ip = data.comment_record_ip; + }, + async getIpLocation () { + // 获取请求IP地址 + console.log('调用获取IP'); + if (process.browser) { + try { + const { data: { query, country, city } } = await this.$axios.get('http://ip-api.com/json', {}); + this.headerConfigs = { ip: query || '', city: city || '', country: country || '' }; + } catch (e) { + this.headerConfigs = {}; + } + } }, submitForm (formName) { this.$refs[formName].validate((valid) => { @@ -180,7 +197,7 @@ export default { }, // 提交评论 async postComment () { - const { data } = await this.$axios.post('/comment', { ...this.postModel, article_id: this.$route.params.id }); + const { data } = await this.$axios.post('/comment', { ...this.postModel, article_id: this.$route.params.id }, { headers: { ...this.headerConfigs } }); if (success(data.code)) { this.$notify({ title: '成功', message: '评论成功', type: 'success' }); this.resetForm('postForm'); diff --git a/nuxt/modules/pages/archive/index.vue b/nuxt/modules/pages/archive/index.vue index c6a9f84..a6f1dad 100644 --- a/nuxt/modules/pages/archive/index.vue +++ b/nuxt/modules/pages/archive/index.vue @@ -39,14 +39,18 @@ export default { return { tagLists: [], archiveLists: {}, - list: {} + list: {}, + headerConfigs: {} } }, async fetch () { - await this.getBannerData(); await this.getTagLists(); await this.getArchiveLists(); }, + async created () { + await this.getIpLocation(); + await this.getBannerData(); + }, head () { return { title: '归档' @@ -56,7 +60,7 @@ export default { // 获取banner数据 async getBannerData () { try { - const { data: { data } } = await this.$axios.get('/site-config/list', {}); + const { data: { data } } = await this.$axios.get('/site-config/list', { headers: { ...this.headerConfigs } }); // 查找数据与路由进行对应 const index = data.list.findIndex(v => v.link === this.$route.path); this.list = data.list[index]; @@ -64,6 +68,17 @@ export default { this.$nuxt.error({ ...e.response.data }); } }, + async getIpLocation () { + // 获取请求IP地址 + if (process.browser) { + try { + const { data: { query, country, city } } = await this.$axios.get('http://ip-api.com/json', {}); + this.headerConfigs = { ip: query || '', city: city || '', country: country || '' }; + } catch (e) { + this.headerConfigs = {}; + } + } + }, async getTagLists () { const { data: { data } } = await this.$axios.get('/archive/tag/list', { params: { 'no-pagination': true } }) this.tagLists = data; diff --git a/nuxt/modules/pages/chain/index.vue b/nuxt/modules/pages/chain/index.vue index 1ab1ab2..a15cb4c 100644 --- a/nuxt/modules/pages/chain/index.vue +++ b/nuxt/modules/pages/chain/index.vue @@ -38,13 +38,17 @@ export default { data () { return { list: {}, - chainLists: [] + chainLists: [], + headerConfigs: {} } }, async fetch () { - await this.getBannerData(); await this.getChainLists(); }, + async created () { + await this.getIpLocation(); + await this.getBannerData(); + }, head () { return { title: '友链' @@ -54,7 +58,7 @@ export default { // 获取banner数据 async getBannerData () { try { - const { data: { data } } = await this.$axios.get('/site-config/list', {}); + const { data: { data } } = await this.$axios.get('/site-config/list', { headers: { ...this.headerConfigs } }); // 查找数据与路由进行对应 const index = data.list.findIndex(v => v.link === this.$route.path); this.list = data.list[index]; @@ -70,7 +74,18 @@ export default { // 跳转友链 navigationChainHandle (chain) { window.open(chain.link, '_blank'); - } + }, + async getIpLocation () { + // 获取请求IP地址 + if (process.browser) { + try { + const { data: { query, country, city } } = await this.$axios.get('http://ip-api.com/json', {}); + this.headerConfigs = { ip: query || '', city: city || '', country: country || '' }; + } catch (e) { + this.headerConfigs = {}; + } + } + }, } } diff --git a/nuxt/modules/pages/index.vue b/nuxt/modules/pages/index.vue index d3c5035..77b9dbe 100644 --- a/nuxt/modules/pages/index.vue +++ b/nuxt/modules/pages/index.vue @@ -33,13 +33,12 @@ export default { author: '' }, count: 0, - list: {} + list: {}, + headerConfigs: {} } }, async fetch () { - await this.getBannerData(); await this.getSiteMetaConfig(); - await this.getArticleLists(); }, head () { return { @@ -51,11 +50,16 @@ export default { ] } }, + async created () { + await this.getIpLocation(); + await this.getBannerData(); + await this.getArticleLists(); + }, methods: { // 获取banner数据 async getBannerData () { try { - const { data: { data } } = await this.$axios.get('/site-config/list', {}); + const { data: { data } } = await this.$axios.get('/site-config/list', { headers: { ...this.headerConfigs } }); // 查找数据与路由进行对应 const index = data.list.findIndex(v => v.link === this.$route.path); this.list = data.list[index]; @@ -68,6 +72,17 @@ export default { const { data: { data } } = await this.$axios.get('/site-config/site'); this.meta = data; }, + async getIpLocation () { + // 获取请求IP地址 + if (process.browser) { + try { + const { data: { query, country, city } } = await this.$axios.get('http://ip-api.com/json', {}); + this.headerConfigs = { ip: query || '', city: city || '', country: country || '' }; + } catch (e) { + this.headerConfigs = {}; + } + } + }, // 获取文章列表渲染 async getArticleLists () { try { diff --git a/server/modules/src/middleware/blacklist.middleware.ts b/server/modules/src/middleware/blacklist.middleware.ts index e944372..4230d99 100644 --- a/server/modules/src/middleware/blacklist.middleware.ts +++ b/server/modules/src/middleware/blacklist.middleware.ts @@ -12,8 +12,7 @@ import {LocationService} from 'src/modules/location/location.service'; export class BlacklistMiddleware implements NestMiddleware { constructor( @InjectRepository(BlacklistEntity) private readonly blackRepository: Repository, - @InjectRepository(OptionsEntity) private readonly optionRepository: Repository, - private readonly locationService: LocationService + @InjectRepository(OptionsEntity) private readonly optionRepository: Repository ) {} private async deleteBlackList (id) { @@ -32,15 +31,18 @@ export class BlacklistMiddleware implements NestMiddleware { return false; } const nowTime = Number(Math.round(new Date().getTime()/1000)); - const { query_ip_location: { result } } = await this.locationService.getLocation(); - const blacklist = await this.blackRepository.findOne({ip: result.ip}); - if (blacklist) { - // 时间过期则删除,否则更新次数 - if (nowTime > blacklist.exp) { - this.deleteBlackList(blacklist.id) - } else { - this.updateBlackListCount(result.ip, blacklist.count + 1); - throw new ForbiddenException('访问被拒绝'); + // 通过前端来传递访问ip + const ip: any = request.headers['ip']; + if (ip) { + const blacklist = await this.blackRepository.findOne({ip}); + if (blacklist) { + // 时间过期则删除,否则更新次数 + if (nowTime > blacklist.exp) { + this.deleteBlackList(blacklist.id) + } else { + this.updateBlackListCount(ip, blacklist.count + 1); + throw new ForbiddenException('访问被拒绝'); + } } } next(); diff --git a/server/modules/src/modules/comment/comment.controller.ts b/server/modules/src/modules/comment/comment.controller.ts index e08b859..95c46f0 100644 --- a/server/modules/src/modules/comment/comment.controller.ts +++ b/server/modules/src/modules/comment/comment.controller.ts @@ -1,4 +1,4 @@ -import {Controller, Post, Body, Query, Get, UsePipes, Delete, UploadedFile, UseInterceptors, HttpService} from '@nestjs/common'; +import {Controller, Post, Body, Query, Get, UsePipes, Delete, UploadedFile, UseInterceptors, HttpService, Headers} from '@nestjs/common'; import {CommentService} from './comment.service'; import {AuthStrategy} from 'src/auth/auth.decorator'; import {ValidateToEmptyPipe} from 'src/pipe/validateToEmptyPipe.pipe'; @@ -53,8 +53,8 @@ export class CommentController { @UsePipes(new ValidateToEmptyPipe([ 'email', 'username', 'content', 'article_id' ])) @RateLimit({ points: 5, duration: 60}) @UseInterceptors(RateLimiterInterceptor) - protected createComment (@Body() body) { - return this.commentService.createComment(body); + protected createComment (@Body() body, @Headers('ip') ip) { + return this.commentService.createComment(body, ip); } /** @@ -76,7 +76,7 @@ export class CommentController { * */ @Get('/switch') protected getCommentSwitchStatus () { - return this.commentService.getCommentSwitchStatus(['comment_status']); + return this.commentService.getCommentSwitchStatus(['comment_status', 'comment_record_ip']); } /** * @desc 获取评论开启状态及记录IP状态 diff --git a/server/modules/src/modules/comment/comment.service.ts b/server/modules/src/modules/comment/comment.service.ts index 787019d..8b40383 100644 --- a/server/modules/src/modules/comment/comment.service.ts +++ b/server/modules/src/modules/comment/comment.service.ts @@ -152,7 +152,7 @@ export class CommentService { * @param data {Object} email, content article_id * @return create result * */ - public async createComment (data) { + public async createComment (data, getHeadersIp) { const { email, content, article_id, username, captcha } = data; const value = await this.optionsRepository.createQueryBuilder('options') .select(['options.key', 'options.value']) @@ -189,8 +189,12 @@ export class CommentService { throw new BadRequestException(MESSAGES.WEBSERVICE_KEY_EMPTY); } // 获取IP地址,IP解析实际地址 - const {query_ip_location: { result: {ip} }, detail_location: { result: { address } } } = await this.locationService.getLocation(); - Object.assign(params, {ip, address}); + if (getHeadersIp) { + const {query_ip_location: { result: {ip} }, detail_location: { result: { address } } } = await this.locationService.getLocation(getHeadersIp); + Object.assign(params, {ip, address}); + } else { + Object.assign(params, {ip: '无法获取', address: '无法获取'}); + } } // 过滤空格,转换小写 const text = content.toLowerCase().replace(/\s*/g, ''); From 08ebcbdadcde7ef8c8264664129d61b4f240dfa7 Mon Sep 17 00:00:00 2001 From: brian lee Date: Thu, 30 Dec 2021 15:09:41 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=8B=E9=93=BEpost?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=E6=A0=A1=E9=AA=8C=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nuxt/modules/components/post-chain.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nuxt/modules/components/post-chain.vue b/nuxt/modules/components/post-chain.vue index 59bcd64..6b4aa8e 100644 --- a/nuxt/modules/components/post-chain.vue +++ b/nuxt/modules/components/post-chain.vue @@ -4,16 +4,16 @@
- + - + - + - + 提 交