Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit02ffdd0

Browse files
author
Julien Neuhart
committed
wip, almost done
1 parent608d3f3 commit02ffdd0

31 files changed

+908
-82
lines changed

‎sources/app/.eslintrc.json‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,8 @@
1212
"extends": [
1313
"eslint:recommended",
1414
"plugin:vue/recommended"
15-
]
15+
],
16+
"rules": {
17+
"indent": ["error",2]
18+
}
1619
}

‎sources/app/assets/vue/App.vue‎

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@
3939
>
4040
<aclass="nav-link">Posts</a>
4141
</router-link>
42+
<li
43+
v-if="isAuthenticated"
44+
class="nav-item"
45+
>
46+
<a
47+
class="nav-link"
48+
href="/api/security/logout"
49+
>Logout</a>
50+
</li>
4251
</ul>
4352
</div>
4453
</nav>
@@ -48,7 +57,34 @@
4857
</template>
4958

5059
<script>
51-
exportdefault {
52-
name:"App",
53-
}
60+
importaxiosfrom"axios";
61+
62+
exportdefault {
63+
name:"App",
64+
computed: {
65+
isAuthenticated() {
66+
returnthis.$store.getters["security/isAuthenticated"]
67+
},
68+
},
69+
created() {
70+
let isAuthenticated=JSON.parse(this.$parent.$el.attributes["data-is-authenticated"].value),
71+
user=JSON.parse(this.$parent.$el.attributes["data-user"].value);
72+
73+
let payload= { isAuthenticated: isAuthenticated, user: user };
74+
this.$store.dispatch("security/onRefresh", payload);
75+
76+
axios.interceptors.response.use(undefined, (err)=> {
77+
returnnewPromise(()=> {
78+
if (err.response.status===401) {
79+
this.$router.push({path:"/login"})
80+
}elseif (err.response.status===500) {
81+
document.open();
82+
document.write(err.response.data);
83+
document.close();
84+
}
85+
throw err;
86+
});
87+
});
88+
},
89+
}
5490
</script>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
importaxiosfrom"axios";
2+
3+
exportdefault{
4+
login(login,password){
5+
returnaxios.post("/api/security/login",{
6+
username:login,
7+
password:password
8+
});
9+
}
10+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<template>
2+
<div
3+
class="alert alert-danger"
4+
role="alert"
5+
>
6+
{{ error.response.data.error }}
7+
</div>
8+
</template>
9+
10+
<script>
11+
exportdefault {
12+
name:"ErrorMessage",
13+
props: {
14+
error: {
15+
type:Object,
16+
required:true
17+
}
18+
},
19+
}
20+
</script>

‎sources/app/assets/vue/components/Post.vue‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export default {
1212
props: {
1313
message: {
1414
type:String,
15-
required:true,
15+
required:true
1616
}
1717
}
1818
};
Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,37 @@
11
importVuefrom"vue";
22
importVueRouterfrom"vue-router";
3+
importstorefrom"../store";
34
importHomefrom"../views/Home";
5+
importLoginfrom"../views/Login";
46
importPostsfrom"../views/Posts";
57

68
Vue.use(VueRouter);
79

8-
exportdefaultnewVueRouter({
10+
letrouter=newVueRouter({
911
mode:"history",
1012
routes:[
1113
{path:"/home",component:Home},
12-
{path:"/posts",component:Posts},
14+
{path:"/login",component:Login},
15+
{path:"/posts",component:Posts,meta:{requiresAuth:true}},
1316
{path:"*",redirect:"/home"}
14-
]
17+
],
1518
});
19+
20+
router.beforeEach((to,from,next)=>{
21+
if(to.matched.some(record=>record.meta.requiresAuth)){
22+
// this route requires auth, check if logged in
23+
// if not, redirect to login page.
24+
if(store.getters["security/isAuthenticated"]){
25+
next();
26+
}else{
27+
next({
28+
path:"/login",
29+
query:{redirect:to.fullPath}
30+
});
31+
}
32+
}else{
33+
next();// make sure to always call next()!
34+
}
35+
});
36+
37+
exportdefaultrouter;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
importVuefrom"vue";
22
importVuexfrom"vuex";
3+
importSecurityModulefrom"./security";
34
importPostModulefrom"./post";
45

56
Vue.use(Vuex);
67

78
exportdefaultnewVuex.Store({
89
modules:{
10+
security:SecurityModule,
911
post:PostModule
1012
}
1113
});
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
importSecurityAPIfrom"../api/security";
2+
3+
constAUTHENTICATING="AUTHENTICATING",
4+
AUTHENTICATING_SUCCESS="AUTHENTICATING_SUCCESS",
5+
AUTHENTICATING_ERROR="AUTHENTICATING_ERROR",
6+
PROVIDING_DATA_ON_REFRESH_SUCCESS="PROVIDING_DATA_ON_REFRESH_SUCCESS";
7+
8+
exportdefault{
9+
namespaced:true,
10+
state:{
11+
isLoading:false,
12+
error:null,
13+
isAuthenticated:false,
14+
user:null
15+
},
16+
getters:{
17+
isLoading(state){
18+
returnstate.isLoading;
19+
},
20+
hasError(state){
21+
returnstate.error!==null;
22+
},
23+
error(state){
24+
returnstate.error;
25+
},
26+
isAuthenticated(state){
27+
returnstate.isAuthenticated;
28+
},
29+
hasRole(state){
30+
returnrole=>{
31+
returnstate.user.roles.indexOf(role)!==-1;
32+
}
33+
}
34+
},
35+
mutations:{
36+
[AUTHENTICATING](state){
37+
state.isLoading=true;
38+
state.error=null;
39+
state.isAuthenticated=false;
40+
state.user=null;
41+
},
42+
[AUTHENTICATING_SUCCESS](state,user){
43+
state.isLoading=false;
44+
state.error=null;
45+
state.isAuthenticated=true;
46+
state.user=user;
47+
},
48+
[AUTHENTICATING_ERROR](state,error){
49+
state.isLoading=false;
50+
state.error=error;
51+
state.isAuthenticated=false;
52+
state.user=null;
53+
},
54+
[PROVIDING_DATA_ON_REFRESH_SUCCESS](state,payload){
55+
state.isLoading=false;
56+
state.error=null;
57+
state.isAuthenticated=payload.isAuthenticated;
58+
state.user=payload.user;
59+
}
60+
},
61+
actions:{
62+
asynclogin({commit},payload){
63+
commit(AUTHENTICATING);
64+
try{
65+
letresponse=awaitSecurityAPI.login(payload.login,payload.password);
66+
commit(AUTHENTICATING_SUCCESS,response.data);
67+
returnresponse.data;
68+
}catch(error){
69+
commit(AUTHENTICATING_ERROR,error);
70+
returnnull;
71+
}
72+
},
73+
onRefresh({commit},payload){
74+
commit(PROVIDING_DATA_ON_REFRESH_SUCCESS,payload);
75+
}
76+
}
77+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<template>
2+
<div>
3+
<divclass="row col">
4+
<h1>Login</h1>
5+
</div>
6+
7+
<divclass="row col">
8+
<form>
9+
<divclass="form-row">
10+
<divclass="col-4">
11+
<input
12+
v-model="login"
13+
type="text"
14+
class="form-control"
15+
>
16+
</div>
17+
<divclass="col-4">
18+
<input
19+
v-model="password"
20+
type="password"
21+
class="form-control"
22+
>
23+
</div>
24+
<divclass="col-4">
25+
<button
26+
:disabled="login.length === 0 || password.length === 0 || isLoading"
27+
type="button"
28+
class="btn btn-primary"
29+
@click="performLogin()"
30+
>
31+
Login
32+
</button>
33+
</div>
34+
</div>
35+
</form>
36+
</div>
37+
38+
<div
39+
v-if="isLoading"
40+
class="row col"
41+
>
42+
<p>Loading...</p>
43+
</div>
44+
45+
<div
46+
v-else-if="hasError"
47+
class="row col"
48+
>
49+
<error-message:error="error" />
50+
</div>
51+
</div>
52+
</template>
53+
54+
<script>
55+
importErrorMessagefrom"../components/ErrorMessage";
56+
57+
exportdefault {
58+
name:"Login",
59+
components: {
60+
ErrorMessage,
61+
},
62+
data() {
63+
return {
64+
login:"",
65+
password:""
66+
};
67+
},
68+
computed: {
69+
isLoading() {
70+
returnthis.$store.getters["security/isLoading"];
71+
},
72+
hasError() {
73+
returnthis.$store.getters["security/hasError"];
74+
},
75+
error() {
76+
returnthis.$store.getters["security/error"];
77+
}
78+
},
79+
created() {
80+
let redirect=this.$route.query.redirect;
81+
82+
if (this.$store.getters["security/isAuthenticated"]) {
83+
if (typeof redirect!=="undefined") {
84+
this.$router.push({path: redirect});
85+
}else {
86+
this.$router.push({path:"/home"});
87+
}
88+
}
89+
},
90+
methods: {
91+
asyncperformLogin() {
92+
let payload= {login:this.$data.login, password:this.$data.password},
93+
redirect=this.$route.query.redirect;
94+
95+
awaitthis.$store.dispatch("security/login", payload);
96+
if (!this.$store.getters["security/hasError"]) {
97+
if (typeof redirect!=="undefined") {
98+
this.$router.push({path: redirect});
99+
}else {
100+
this.$router.push({path:"/home"});
101+
}
102+
}
103+
}
104+
}
105+
}
106+
</script>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp