├── .gitignore
├── README.md
├── jwt-pure-js
├── README.md
├── js
│ ├── lib
│ │ ├── jquery-1.12.4.js
│ │ └── vue.js
│ └── util
│ │ └── util.js
└── views
│ ├── index.html
│ └── login.html
└── vue-jwt-demo
├── README.md
├── index.html
├── npm-debug.log
├── package-lock.json
├── package.json
├── src
├── App.vue
├── assets
│ └── logo.png
├── auth
│ └── auth.js
├── component
│ ├── Home.vue
│ └── Login.vue
├── main.js
└── util
│ └── net.js
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | vue-jwt-demo/node_modules
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # 说明
3 |
4 | 本项目有2个关于前后端分离的前端实现
5 |
6 | 1. vue-jwt-demo: 使用vue js构建
7 | 2. jwt-pure-js: 使用传统js构建
8 |
9 | **2018-08修改:**
10 |
11 | 将token放在header里改为放在参数里传递
12 |
--------------------------------------------------------------------------------
/jwt-pure-js/README.md:
--------------------------------------------------------------------------------
1 | # 介绍
2 | 纯的js+jquery+vue.js
3 |
--------------------------------------------------------------------------------
/jwt-pure-js/js/util/util.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * 网络请求封装模块
4 | */
5 | var net = {
6 | HOST: "http://localhost:8081",
7 | /**
8 | * JSON请求,后台使用RequestBody接收数据
9 | */
10 | postJson: function (url, data, callback) {
11 | $.ajax({
12 | url: net.HOST + url,
13 | type: "POST",
14 | dataType: "json",
15 | contentType: "application/json;charset=utf-8",
16 | data: JSON.stringify(data),
17 | success: function (re) {
18 | if (re.ok) {
19 | callback(re);
20 | } else {
21 | console.log(re.msg);
22 | }
23 | },
24 | error: function (e) {
25 | console.log(e)
26 | alert("error")
27 | }
28 | })
29 | }
30 | }
31 |
32 | /**
33 | * 本地存储模块
34 | */
35 | var storage = {
36 | TOKEN_KEY: "token_key",
37 | /**
38 | * 存储token到cookie
39 | */
40 | tokenStore: function (token) {
41 | console.log(document.cookie)
42 | // cookie.setCookie(storage.TOKEN_KEY, token, 1);
43 | sessionStorage.TOKEN_KEY = token;
44 | },
45 | /**
46 | * 获取token
47 | */
48 | tokenGet: function () {
49 | // var token = cookie.getCookie(storage.TOKEN_KEY);
50 | // return token;
51 | return sessionStorage.TOKEN_KEY;
52 | },
53 | isTokenValid: function () {
54 | if (storage.tokenGet() === null) {
55 | return false;
56 | }
57 | return true;
58 | }
59 | }
60 |
61 | /**
62 | * js操作cookie工具类
63 | */
64 | var cookie = {
65 | //写cookies
66 | setCookie: function (cname, cvalue, exdays) {
67 | var d = new Date();
68 | d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
69 | var expires = "expires=" + d.toGMTString();
70 | document.cookie = cname + "=" + cvalue + "; " + expires;
71 | },
72 | //读取cookies
73 | getCookie: function (cname) {
74 | var name = cname + "=";
75 | var ca = document.cookie.split(';');
76 | for (var i = 0; i < ca.length; i++) {
77 | var c = ca[i].trim();
78 | if (c.indexOf(name) == 0) { return c.substring(name.length, c.length); }
79 | }
80 | return "";
81 | },
82 | //删除cookies
83 | delCookie: function (name) {
84 | var exp = new Date();
85 | exp.setTime(exp.getTime() - 1);
86 | var cval = cookie.getCookie(name);
87 | if (cval != null) {
88 | document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/jwt-pure-js/views/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Vue.js learn
7 |
8 |
9 |
10 |
11 |
12 | {{email}}
13 |
14 |
15 |
16 | {{message}}
17 |
18 |
19 |
20 | move on
21 |
22 |
23 |
26 |
27 |
28 | - {{todo.text}}
29 |
30 |
31 |
32 |
{{message}}
33 |
34 |
35 |
39 |
45 |
46 |
47 |
48 |
49 |
50 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/jwt-pure-js/views/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Login
7 |
8 |
9 |
10 | 前后端分离登录
11 |
12 | Name:
13 |
Password:
14 |
15 |
16 |
{{error}}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/vue-jwt-demo/README.md:
--------------------------------------------------------------------------------
1 | # vue-jwt-demo
2 |
3 | > 一个最简单的vue.js项目,实现了前后端分离的基本功能
4 | > 对应的java后台:https://github.com/jimolonely/AuthServer
5 |
6 | ## Build Setup
7 |
8 | ``` bash
9 | # install dependencies
10 | npm install
11 |
12 | # serve with hot reload at localhost:8080
13 | npm run dev
14 |
15 | # build for production with minification
16 | npm run build
17 | ```
18 |
19 | For detailed explanation on how things work, consult the [docs for vue-loader](http://vuejs.github.io/vue-loader).
20 |
--------------------------------------------------------------------------------
/vue-jwt-demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | vue-jwt-demo
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/vue-jwt-demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-jwt-demo",
3 | "description": "A Vue.js project",
4 | "version": "1.0.0",
5 | "author": "jimolonely",
6 | "private": true,
7 | "scripts": {
8 | "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
9 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
10 | },
11 | "dependencies": {
12 | "jquery": "^3.2.1",
13 | "vue": "^2.5.17",
14 | "vue-resource": "^1.5.1",
15 | "vue-router": "^3.0.1"
16 | },
17 | "devDependencies": {
18 | "babel-core": "^6.0.0",
19 | "babel-loader": "^6.0.0",
20 | "babel-preset-latest": "^6.0.0",
21 | "cross-env": "^3.0.0",
22 | "css-loader": "^0.25.0",
23 | "file-loader": "^0.9.0",
24 | "vue-loader": "^11.1.4",
25 | "vue-template-compiler": "^2.2.1",
26 | "webpack": "^2.2.0",
27 | "webpack-dev-server": "^2.2.0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/vue-jwt-demo/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{msg}}
4 |
5 |
6 |
7 |
8 |
18 |
19 |
47 |
--------------------------------------------------------------------------------
/vue-jwt-demo/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimolonely/vue-jwt-demo/1b028cb051302ac07c2d18d9e5ce7a3692a3799b/vue-jwt-demo/src/assets/logo.png
--------------------------------------------------------------------------------
/vue-jwt-demo/src/auth/auth.js:
--------------------------------------------------------------------------------
1 |
2 | const SERVER_URL = 'http://localhost:8081'
3 | const LOGIN_URL = SERVER_URL + '/user/login'
4 |
5 | import net from '../util/net';
6 |
7 | export default {
8 | data: {
9 | authenticated: false
10 | },
11 | // login(context, info) {
12 | // net.postJson('/user/login', info, function (token) {
13 | // localStorage.setItem('token', token);
14 | // this.$router.push('home');
15 | // })
16 | // context.$http.post(LOGIN_URL, info).then(function (data) {
17 | // console.log(data)
18 | // var re = data.body;
19 | // console.log(re.ok);
20 | // if (re.ok) {
21 | // localStorage.setItem('token', re.data);
22 | // this.authenticated = true
23 | // this.$router.push('home')
24 | // } else {
25 | // console.log(re)
26 | // }
27 | // }, function (err) {
28 | // console.log(err + "," + err.body.message)
29 | // context.error = err.body.message
30 | // })
31 | // },
32 | getAuthHeader() {
33 | return {
34 | 'Authorization': 'Bearer ' + localStorage.getItem('token')
35 | }
36 | },
37 | checkAuth(context) {
38 | var token = localStorage.getItem('token')
39 | if (token) {
40 | this.authenticated = true
41 | } else {
42 | this.authenticated = false
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/vue-jwt-demo/src/component/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{msg}}
4 |
5 |
Email:{{email}}
6 |
7 |
8 |
Token:{{token}}
9 |
10 |
11 |
12 |
71 |
72 |
91 |
--------------------------------------------------------------------------------
/vue-jwt-demo/src/component/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
登录
4 |
{{ error }}
5 |
6 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
52 |
--------------------------------------------------------------------------------
/vue-jwt-demo/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import Login from './component/Login.vue'
4 | import Home from './component/Home.vue'
5 | import VueRouter from 'vue-router'
6 | import VueResource from 'vue-resource'
7 | import auth from './auth/auth'
8 |
9 | Vue.use(VueRouter)
10 | Vue.use(VueResource)
11 |
12 | //在启动APP时进行校验是否有token
13 | auth.checkAuth()
14 |
15 | const routes= [
16 | {
17 | path:'/',redirect:'/login'
18 | },
19 | {
20 | path:'/login',component:Login
21 | },
22 | {
23 | path:'/home',component:Home
24 | }
25 | ]
26 |
27 | const router = new VueRouter({
28 | routes
29 | })
30 | new Vue({
31 | router,
32 | render: h => h(App)
33 | }).$mount('#app')
34 |
--------------------------------------------------------------------------------
/vue-jwt-demo/src/util/net.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 本工具类与网络相关
3 | */
4 | import $ from 'jquery';
5 |
6 | const SERVER_URL = 'http://localhost:8081/'
7 |
8 | export default {
9 | /**
10 | * 检查token是否合法,需要服务器认证
11 | */
12 | isTokenValid() {
13 | var token = localStorage.getItem('token');
14 | if (token) {
15 | this.get("user/checkToken?token=" + token, function () {
16 | return true;
17 | })
18 | } else {
19 | console.log("token不存在")
20 | this.$router.push('login');
21 | }
22 | },
23 | /**
24 | * token放在header里后台接受不到,放在参数里一起传递
25 | */
26 | postJson(url, json, callback) {
27 | var token = localStorage.getItem('token');
28 | if (token || url === "user/login") {
29 | json.Authorization = 'Bearer ' + token;
30 | console.log(json)
31 | $.ajax({
32 | url: SERVER_URL + url,
33 | type: 'POST',
34 | dataType: 'json',
35 | contentType: 'application/json;charset=utf-8',
36 | data: JSON.stringify(json),
37 | success: function (re) {
38 | console.log(re)
39 | if (re.ok) {
40 | callback(re.data);
41 | } else {
42 | alert(re.msg);
43 | }
44 | },
45 | error: function (e) {
46 | console.log(e)
47 | }
48 | })
49 | } else {
50 | console.log("token不存在")
51 | this.$router.push('login');
52 | }
53 | },
54 | get(url, callback, context) {
55 | var token = localStorage.getItem('token');
56 | if (token) {
57 | $.ajax({
58 | url: SERVER_URL + url,
59 | type: "GET",
60 | beforeSend: function (xhr) {
61 | xhr.setRequestHeader("Authorization", 'Bearer ' + token);
62 | },
63 | data: {
64 | Authorization: 'Bearer ' + token
65 | }
66 | }).then(function (re, status, jqxhr) {
67 | console.log(jqxhr);
68 | console.log(status);
69 | console.log(re)
70 | if (re.ok) {
71 | callback(re.data);
72 | } else {
73 | alert(re.msg);
74 | }
75 | });
76 |
77 | // $.ajax({
78 | // url: SERVER_URL + url,
79 | // type: 'GET',
80 | // dataType: 'JSON',
81 | // // beforeSend: function (xhr) {
82 | // // xhr.setRequestHeader("Authorization", 'Bearer ' + token);
83 | // // },
84 | // headers: {
85 | // "Authorization": "Bearer " + token
86 | // },
87 | // success: function (re) {
88 | // if (re.ok) {
89 | // callback(re.data);
90 | // } else {
91 | // alert(re.msg);
92 | // }
93 | // },
94 | // error: function (e) {
95 | // console.log(e)
96 | // }
97 | // })
98 | } else {
99 | console.log("token不存在")
100 | context.$router.push('login');
101 | }
102 | },
103 | post(url, json, callback, context) {
104 | var token = localStorage.getItem('token');
105 | if (token) {
106 | json.Authorization = 'Bearer ' + token;
107 | $.ajax({
108 | url: SERVER_URL + url,
109 | type: 'POST',
110 | data: json,
111 | success: function (re) {
112 | console.log(re)
113 | if (re.ok) {
114 | callback(re.data);
115 | } else {
116 | alert(re.msg);
117 | }
118 | },
119 | error: function (e) {
120 | console.log(e)
121 | }
122 | })
123 | } else {
124 | console.log("token不存在")
125 | context.$router.push('login');
126 | }
127 | }
128 | }
--------------------------------------------------------------------------------
/vue-jwt-demo/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var webpack = require('webpack')
3 | module.exports = {
4 | entry: './src/main.js',
5 | output: {
6 | path: path.resolve(__dirname, './dist'),
7 | publicPath: '/dist/',
8 | filename: 'build.js'
9 | },
10 | module: {
11 | rules: [
12 | {
13 | test: /\.vue$/,
14 | loader: 'vue-loader',
15 | options: {
16 | loaders: {
17 | }
18 | // other vue-loader options go here
19 | }
20 | },
21 | {
22 | test: /\.js$/,
23 | loader: 'babel-loader',
24 | exclude: /node_modules/
25 | },
26 | {
27 | test: /\.(png|jpg|gif|svg)$/,
28 | loader: 'file-loader',
29 | options: {
30 | name: '[name].[ext]?[hash]'
31 | }
32 | }
33 | ]
34 | },
35 | resolve: {
36 | alias: {
37 | 'vue$': 'vue/dist/vue.esm.js'
38 | }
39 | },
40 | devServer: {
41 | historyApiFallback: true,
42 | noInfo: true
43 | },
44 | performance: {
45 | hints: false
46 | },
47 | devtool: '#eval-source-map'
48 | }
49 |
50 | if (process.env.NODE_ENV === 'production') {
51 | module.exports.devtool = '#source-map'
52 | // http://vue-loader.vuejs.org/en/workflow/production.html
53 | module.exports.plugins = (module.exports.plugins || []).concat([
54 | new webpack.DefinePlugin({
55 | 'process.env': {
56 | NODE_ENV: '"production"'
57 | }
58 | }),
59 | new webpack.optimize.UglifyJsPlugin({
60 | sourceMap: true,
61 | compress: {
62 | warnings: false
63 | }
64 | }),
65 | new webpack.LoaderOptionsPlugin({
66 | minimize: true
67 | })
68 | ])
69 | }
70 |
--------------------------------------------------------------------------------