From c9224590fba55389e115d20fc8841a5a6a05d460 Mon Sep 17 00:00:00 2001 From: yumaojun03 <719118794@qq.com> Date: Sun, 5 Jan 2025 17:15:05 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E7=99=BB=E5=BD=95=E5=90=8E?= =?UTF-8?q?=E5=90=8E=E7=9A=84=E7=8A=B6=E6=80=81=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vblog/apps/token/impl/impl.go | 2 +- vblog/logs/vblog.log | 18 +++++++ vblog/web/README.md | 63 ++++++++++++++++++++++++ vblog/web/package-lock.json | 39 +++++++++++++++ vblog/web/package.json | 1 + vblog/web/src/api/client.js | 22 ++++++++- vblog/web/src/stores/token.js | 14 ++++++ vblog/web/src/views/common/LoginPage.vue | 9 +++- vblog/web/vite.config.js | 13 ++--- 9 files changed, 172 insertions(+), 9 deletions(-) create mode 100644 vblog/web/src/stores/token.js diff --git a/vblog/apps/token/impl/impl.go b/vblog/apps/token/impl/impl.go index 7a44cec..3646eda 100644 --- a/vblog/apps/token/impl/impl.go +++ b/vblog/apps/token/impl/impl.go @@ -56,7 +56,7 @@ func (t *TokenServiceImpl) IssueToken(ctx context.Context, in *token.IssueTokenR // 2. 比对密码 if err := u.CheckPassword(in.Password); err != nil { - return nil, err + return nil, exception.NewUnauthorized("用户名或者密码错误").WithData(err) } // 3. 颁发Token diff --git a/vblog/logs/vblog.log b/vblog/logs/vblog.log index 9b8e251..13616c0 100644 --- a/vblog/logs/vblog.log +++ b/vblog/logs/vblog.log @@ -180,3 +180,21 @@ {"level":"info","component":"server","time":"2025-01-05T16:05:48+08:00","caller":"ioc/server/server.go:76","message":"loaded apis: [blogs.v1 tokens.v1]"} {"level":"info","component":"server","time":"2025-01-05T16:05:48+08:00","caller":"ioc/server/server.go:77","message":"loaded defaults: []"} {"level":"info","component":"http","time":"2025-01-05T16:05:48+08:00","caller":"config/http/http.go:144","message":"HTTP服务启动成功, 监听地址: 127.0.0.1:8080"} +{"level":"debug","time":"2025-01-05T16:45:22+08:00","caller":"token/api/api.go:57","message":"cookie domain: 127.0.0.1"} +{"level":"debug","time":"2025-01-05T16:45:26+08:00","caller":"token/api/api.go:57","message":"cookie domain: 127.0.0.1"} +{"level":"info","component":"server","time":"2025-01-05T17:01:24+08:00","caller":"ioc/server/server.go:101","message":"receive signal 'interrupt', start graceful shutdown"} +{"level":"info","component":"http","time":"2025-01-05T17:01:24+08:00","caller":"config/http/http.go:152","message":"start graceful shutdown"} +{"level":"error","component":"http","time":"2025-01-05T17:01:24+08:00","caller":"config/http/http.go:146","message":"http: Server closed"} +{"level":"info","component":"server","time":"2025-01-05T17:01:24+08:00","caller":"ioc/server/server.go:115","message":"http service stop complete"} +{"level":"info","component":"gin_webframework","time":"2025-01-05T17:01:29+08:00","caller":"config/gin/framework.go:41","message":"enable gin recovery"} +{"level":"debug","time":"2025-01-05T17:01:29+08:00","caller":"token/impl/impl.go:39","message":"DefaultExpiredTTL: 3600"} +{"level":"info","component":"server","time":"2025-01-05T17:01:29+08:00","caller":"ioc/server/server.go:74","message":"loaded configs: [app.v1 trace.v1 log.v1 validator.v1 gin_webframework.v1 datasource.v1 grpc.v1 http.v1]"} +{"level":"info","component":"server","time":"2025-01-05T17:01:29+08:00","caller":"ioc/server/server.go:75","message":"loaded controllers: [token.v1 user.v1 blog.v1]"} +{"level":"info","component":"server","time":"2025-01-05T17:01:29+08:00","caller":"ioc/server/server.go:76","message":"loaded apis: [blogs.v1 tokens.v1]"} +{"level":"info","component":"server","time":"2025-01-05T17:01:29+08:00","caller":"ioc/server/server.go:77","message":"loaded defaults: []"} +{"level":"info","component":"http","time":"2025-01-05T17:01:29+08:00","caller":"config/http/http.go:144","message":"HTTP服务启动成功, 监听地址: 127.0.0.1:8080"} +{"level":"debug","time":"2025-01-05T17:02:36+08:00","caller":"token/api/api.go:57","message":"cookie domain: 127.0.0.1"} +{"level":"debug","time":"2025-01-05T17:02:38+08:00","caller":"token/api/api.go:57","message":"cookie domain: 127.0.0.1"} +{"level":"debug","time":"2025-01-05T17:03:38+08:00","caller":"token/api/api.go:57","message":"cookie domain: 127.0.0.1"} +{"level":"debug","time":"2025-01-05T17:05:11+08:00","caller":"token/api/api.go:57","message":"cookie domain: 127.0.0.1"} +{"level":"debug","time":"2025-01-05T17:12:56+08:00","caller":"token/api/api.go:57","message":"cookie domain: 127.0.0.1"} diff --git a/vblog/web/README.md b/vblog/web/README.md index d31c589..9d7a7fe 100644 --- a/vblog/web/README.md +++ b/vblog/web/README.md @@ -232,3 +232,66 @@ Access to XMLHttpRequest at 'http://127.0.0.1:8080/api/vblog/v1/tokens' from ori ``` ### 如何处理CORS + +- 1. 服务端 允许跨越访问, 服务端需要配置一个CROS 中间件,返回 允许的 origin列表, 允许 origin localhost 访问 +- 2. 前端使用代码, 前端先访问 -- proxy -- backend + +推荐: 前端使用代理 , 最终的效果是 前端和后端部署在一起 + +前端如何配置代理: (vite) + +```js +// https://vite.dev/config/ +export default defineConfig({ + plugins: [vue(), vueJsx(), vueDevTools()], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)), + }, + }, + server: { + proxy: { + '/api': 'http://localhost:8080', + }, + }, +}) +``` + +http client在请求的时候,不能指定baseURL: http://127.0.0.1:8080/api/vblog/v1/tokens, + +``` +http://localhost:5173/api/vblog/v1/tokens --> http://localhost:8080/vblog/v1/tokens +``` + +移除baseURL配置 + +```js +export const client = axios.create({ + baseURL: '', + timeout: 3000, +}) +``` + +### API 访问报错处理 + +添加一个响应拦截器来进行响应的处理 + +```js +// http 客户端配置一个拦截器 +client.interceptors.response.use( + // 请求成功的拦截器 + (value) => { + return value + }, + // 请求失败 + (error) => { + let msg = error.message + try { + msg = error.response.data.message + } catch (error) { + console.log(error) + } + Message.error(msg) + }, +) +``` diff --git a/vblog/web/package-lock.json b/vblog/web/package-lock.json index 479d7a1..2e69385 100644 --- a/vblog/web/package-lock.json +++ b/vblog/web/package-lock.json @@ -8,6 +8,7 @@ "name": "web", "version": "0.0.0", "dependencies": { + "@vueuse/core": "^12.3.0", "axios": "^1.7.9", "pinia": "^2.3.0", "vue": "^3.5.13", @@ -1554,6 +1555,11 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.20", + "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==" + }, "node_modules/@vitejs/plugin-vue": { "version": "5.2.1", "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz", @@ -1802,6 +1808,39 @@ "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.13.tgz", "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==" }, + "node_modules/@vueuse/core": { + "version": "12.3.0", + "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-12.3.0.tgz", + "integrity": "sha512-cnV8QDKZrsyKC7tWjPbeEUz2cD9sa9faxF2YkR8QqNwfofgbOhmfIgvSYmkp+ttSvfOw4E6hLcQx15mRPr0yBA==", + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "12.3.0", + "@vueuse/shared": "12.3.0", + "vue": "^3.5.13" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/metadata": { + "version": "12.3.0", + "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-12.3.0.tgz", + "integrity": "sha512-M/iQHHjMffOv2npsw2ihlUx1CTiBwPEgb7DzByLq7zpg1+Ke8r7s9p5ybUWc5OIeGewtpY4Xy0R2cKqFqM8hFg==", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "12.3.0", + "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-12.3.0.tgz", + "integrity": "sha512-X3YD35GUeW0d5Gajcwv9jdLAJTV2Jdb/Ll6Ii2JIYcKLYZqv5wxyLeKtiQkqWmHg3v0J0ZWjDUMVOw2E7RCXfA==", + "dependencies": { + "vue": "^3.5.13" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/acorn": { "version": "8.14.0", "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.14.0.tgz", diff --git a/vblog/web/package.json b/vblog/web/package.json index 90adee8..e9d02f1 100644 --- a/vblog/web/package.json +++ b/vblog/web/package.json @@ -13,6 +13,7 @@ "format": "prettier --write src/" }, "dependencies": { + "@vueuse/core": "^12.3.0", "axios": "^1.7.9", "pinia": "^2.3.0", "vue": "^3.5.13", diff --git a/vblog/web/src/api/client.js b/vblog/web/src/api/client.js index c5266ab..9489c8f 100644 --- a/vblog/web/src/api/client.js +++ b/vblog/web/src/api/client.js @@ -1,6 +1,26 @@ import axios from 'axios' +import { Message } from '@arco-design/web-vue' export const client = axios.create({ - baseURL: 'http://127.0.0.1:8080', + baseURL: '', timeout: 3000, }) + +// http 客户端配置一个拦截器 +client.interceptors.response.use( + // 请求成功的拦截器 + (value) => { + // 提取出数据里面的data部分 + return value.data + }, + // 请求失败 + (error) => { + let msg = error.message + try { + msg = error.response.data.message + } catch (error) { + console.log(error) + } + Message.error(msg) + }, +) diff --git a/vblog/web/src/stores/token.js b/vblog/web/src/stores/token.js new file mode 100644 index 0000000..4217ab7 --- /dev/null +++ b/vblog/web/src/stores/token.js @@ -0,0 +1,14 @@ +import { useStorage } from '@vueuse/core' + +export const token = useStorage( + 'token', + { + access_token: '', + ref_user_name: '', + refresh_token: '', + }, + localStorage, + { + mergeDefaults: true, + }, +) diff --git a/vblog/web/src/views/common/LoginPage.vue b/vblog/web/src/views/common/LoginPage.vue index 2da3721..9dcbc42 100644 --- a/vblog/web/src/views/common/LoginPage.vue +++ b/vblog/web/src/views/common/LoginPage.vue @@ -36,6 +36,7 @@ import { reactive, ref } from 'vue'; import { LOGIN } from '@/api/token.js' +import { token } from '@/stores/token' const loginForm = reactive({ username: '', @@ -48,7 +49,13 @@ const handleSubmit = async (data) => { if (data.errors === undefined) { try { summitLoading.value = true - await LOGIN(data.values) + const tk = await LOGIN(data.values) + // 保存当前用户的登录状态 + token.value.access_token = tk.access_token + token.value.ref_user_name = tk.ref_user_name + token.value.refresh_token = tk.refresh_token + + // 需要把用户重定向到Home页面去了 } catch (error) { console.log(error) } finally { diff --git a/vblog/web/vite.config.js b/vblog/web/vite.config.js index d49d708..50b5e0c 100644 --- a/vblog/web/vite.config.js +++ b/vblog/web/vite.config.js @@ -7,14 +7,15 @@ import vueDevTools from 'vite-plugin-vue-devtools' // https://vite.dev/config/ export default defineConfig({ - plugins: [ - vue(), - vueJsx(), - vueDevTools(), - ], + plugins: [vue(), vueJsx(), vueDevTools()], resolve: { alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)) + '@': fileURLToPath(new URL('./src', import.meta.url)), + }, + }, + server: { + proxy: { + '/api': 'http://localhost:8080', }, }, })