Showing
62 changed files
with
1578 additions
and
142 deletions
A_Team_Khuloud/khuloud/blog/.views.py.swp
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
A_Team_Khuloud/khuloud/blog/serializers.py
0 → 100644
1 | +from django.contrib.auth.models import User | ||
2 | +from django.contrib.auth import authenticate | ||
3 | +from rest_framework import serializers | ||
4 | + | ||
5 | +# 접속 유지 확인 및 사용자 확인 | ||
6 | +class UserSerializer(serializers.ModelSerializer): | ||
7 | + class Meta: | ||
8 | + model = User | ||
9 | + fields = ['id', 'username', 'email'] | ||
10 | + | ||
11 | +# 회원가입 | ||
12 | +class SignUpSerializer(serializers.ModelSerializer): | ||
13 | + class Meta: | ||
14 | + model = User | ||
15 | + fields = ['username', 'email', 'password'] | ||
16 | + extra_kwargs = {"password": {"write_only": True}} | ||
17 | + | ||
18 | + def create(self, validated_data): | ||
19 | + user = User.objects.create_user( | ||
20 | + validated_data['username'], validated_data['email'], validated_data['password'] | ||
21 | + ) | ||
22 | + | ||
23 | + return user | ||
24 | + | ||
25 | + | ||
26 | +# 로그인 (커스터마이징 => Serializer) | ||
27 | +class LoginSerializer(serializers.Serializer): | ||
28 | + username = serializers.CharField() | ||
29 | + password = serializers.CharField() | ||
30 | + | ||
31 | + def validate(self, data): | ||
32 | + print('validate data',data) | ||
33 | + user = authenticate(**data) | ||
34 | + if user and user.is_active: | ||
35 | + return user | ||
36 | + raise serializers.validationError('Unable to log in with provided credentials.') | ||
37 | + | ||
38 | + | ||
39 | +""" | ||
40 | +class GoogleSerializer(serializers.Serializer): | ||
41 | + Access token = serializers.CharField() | ||
42 | + Code = serializers.CharField() | ||
43 | + | ||
44 | + def validate(self, data): | ||
45 | + print('validate data',data) | ||
46 | + user = authenticate(**data) | ||
47 | + if user and user.is_active: | ||
48 | + return user | ||
49 | + raise serializers.validationError('Unable to log in with provided credentials.') | ||
50 | +""" |
1 | {% extends 'layout.html' %} | 1 | {% extends 'layout.html' %} |
2 | {% block content %} | 2 | {% block content %} |
3 | -<!--이것을 써줘야 socicalaccount기능을 사용할수있음.--> | 3 | +{% load socialaccount %} |
4 | - {%load socialaccount %} | 4 | +{% providers_media_js %} |
5 | - {% providers_media_js %} | 5 | +{% load static %} |
6 | - {% load static %} | 6 | +{% static 'blog/img/naver_login_green.png' as naver_button %} |
7 | - {% static 'blog/img/naver_login_green.png' as naver_button %} | 7 | +{% static 'blog/img/naver_login_white.png' as naver_button_hover %} |
8 | - {% static 'blog/img/naver_login_white.png' as naver_button_hover %} | 8 | +{% static 'blog/img/google_login_normal.png' as google_button %} |
9 | - {% static 'blog/img/google_login_normal.png' as google_button %} | 9 | +{% static 'blog/img/google_login_preesed.png' as google_button_hover %} |
10 | - {% static 'blog/img/google_login_preesed.png' as google_button_hover %} | 10 | + |
11 | <div class="col-md-8 col-md-offset-2"> | 11 | <div class="col-md-8 col-md-offset-2"> |
12 | <div class="panel panel-default"> | 12 | <div class="panel panel-default"> |
13 | <div class="panel-heading">로그인</div> | 13 | <div class="panel-heading">로그인</div> |
14 | <div class="panel-body"> | 14 | <div class="panel-body"> |
15 | <form class="form-horizontal" role="form" method="POST" action="/login/"> | 15 | <form class="form-horizontal" role="form" method="POST" action="/login/"> |
16 | + | ||
16 | <div class="form-group"> | 17 | <div class="form-group"> |
17 | <div class="col-md-12"> | 18 | <div class="col-md-12"> |
18 | <label for="userid">아이디</label> | 19 | <label for="userid">아이디</label> |
19 | <input id="userid" type="userid" class="form-control" name="username" required autofocus> | 20 | <input id="userid" type="userid" class="form-control" name="username" required autofocus> |
20 | </div> | 21 | </div> |
21 | </div> | 22 | </div> |
23 | + | ||
22 | <div class="form-group"> | 24 | <div class="form-group"> |
23 | <div class="col-md-12"> | 25 | <div class="col-md-12"> |
24 | <label for="password">비밀번호</label> | 26 | <label for="password">비밀번호</label> |
25 | <input id="password" type="password" class="form-control" name="password" required> | 27 | <input id="password" type="password" class="form-control" name="password" required> |
26 | </div> | 28 | </div> |
27 | </div> | 29 | </div> |
30 | + | ||
28 | <div class="form-group"> | 31 | <div class="form-group"> |
29 | <div class="col-md-12"> | 32 | <div class="col-md-12"> |
30 | <button type="submit" class="btn btn-success"> | 33 | <button type="submit" class="btn btn-success"> |
... | @@ -34,26 +37,17 @@ | ... | @@ -34,26 +37,17 @@ |
34 | 회원가입 | 37 | 회원가입 |
35 | </button> | 38 | </button> |
36 | </div> | 39 | </div> |
37 | - <a href="{% provider_login_url 'naver' %}"> | ||
38 | - <img src="{{ naver_button }}" | ||
39 | - onmouseover="this.src='{{ naver_button_hover }}'" | ||
40 | - onmouseleave="this.src='{{ naver_button }}'"height="34"> | ||
41 | - </a> | ||
42 | - <br> | ||
43 | - <a href="{% provider_login_url 'google' %}"> | ||
44 | - <img src="{{ google_button }}" | ||
45 | - onmouseover="this.src='{{ google_button_hover }}'" | ||
46 | - onmouseleave="this.src='{{ google_button }}'"height="34"> | ||
47 | - </a> | ||
48 | - <br> | ||
49 | </div> | 40 | </div> |
41 | + | ||
50 | <div class="form-group"> | 42 | <div class="form-group"> |
51 | <div class="col-md-12 text-center"> | 43 | <div class="col-md-12 text-center"> |
52 | <h5>{{ message }}</h5> | 44 | <h5>{{ message }}</h5> |
53 | </div> | 45 | </div> |
54 | </div> | 46 | </div> |
47 | + | ||
55 | </form> | 48 | </form> |
56 | </div> | 49 | </div> |
57 | </div> | 50 | </div> |
58 | </div> | 51 | </div> |
52 | + | ||
59 | {% endblock %} | 53 | {% endblock %} | ... | ... |
A_Team_Khuloud/khuloud/blog/urls.py
0 → 100644
1 | +from django.urls import path, include | ||
2 | +from rest_framework import routers | ||
3 | +from blog.views import LoginAPI,SignUpAPI,UserAPI,GoogleLogin,social_login | ||
4 | + | ||
5 | +# router = routers.DefaultRouter() | ||
6 | +# router.register(r'user', views.login) | ||
7 | + | ||
8 | +urlpatterns = [ | ||
9 | + path("api/auth/signUp", SignUpAPI.as_view()), | ||
10 | + path("api/auth/login", LoginAPI.as_view()), | ||
11 | + path("api/auth/loadMe", UserAPI.as_view()), | ||
12 | + path('rest-auth/google', GoogleLogin.as_view()), | ||
13 | + # path('accounts/', GoogleLogin.as_view()), | ||
14 | + path('accounts/google/login/callback/main/', social_login) | ||
15 | +] |
... | @@ -2,6 +2,7 @@ from django.contrib.auth.models import User | ... | @@ -2,6 +2,7 @@ from django.contrib.auth.models import User |
2 | from django.contrib.auth import authenticate | 2 | from django.contrib.auth import authenticate |
3 | from django.shortcuts import render, redirect | 3 | from django.shortcuts import render, redirect |
4 | from django.core.exceptions import PermissionDenied | 4 | from django.core.exceptions import PermissionDenied |
5 | +from rest_framework.authtoken.models import Token | ||
5 | from khuloud import settings | 6 | from khuloud import settings |
6 | from blog import cognito | 7 | from blog import cognito |
7 | from django.views.decorators.csrf import csrf_exempt | 8 | from django.views.decorators.csrf import csrf_exempt |
... | @@ -9,115 +10,107 @@ from django.http import HttpResponse, JsonResponse | ... | @@ -9,115 +10,107 @@ from django.http import HttpResponse, JsonResponse |
9 | from django.views.decorators.csrf import csrf_exempt | 10 | from django.views.decorators.csrf import csrf_exempt |
10 | from django.utils.decorators import method_decorator | 11 | from django.utils.decorators import method_decorator |
11 | from rest_framework.response import Response | 12 | from rest_framework.response import Response |
12 | -from rest_framework import status | 13 | +from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter |
14 | +from rest_auth.registration.views import SocialLoginView | ||
15 | +from rest_auth.registration.serializers import SocialLoginSerializer,SocialAccountSerializer | ||
16 | +from allauth.socialaccount.models import SocialToken | ||
17 | +from allauth.socialaccount.providers.oauth2.client import OAuth2Client | ||
18 | +from blog.serializers import ( | ||
19 | + LoginSerializer, | ||
20 | + SignUpSerializer, | ||
21 | + UserSerializer, | ||
22 | +) | ||
23 | + | ||
24 | +from rest_framework import viewsets, permissions, generics, status | ||
13 | from cloud import views | 25 | from cloud import views |
26 | +from django.views.generic import View | ||
14 | import hashlib | 27 | import hashlib |
15 | import json | 28 | import json |
16 | import django | 29 | import django |
17 | import requests | 30 | import requests |
18 | -@csrf_exempt | 31 | +def social_login(request): |
19 | -def main(request): | 32 | + print('zzz') |
20 | - if request.user.is_authenticated: | 33 | + # token=request.POST["access_token"] |
21 | - return render(request, "main.html") | 34 | + user=request.user |
22 | - else: | 35 | + token, created = Token.objects.get_or_create(user=user) |
23 | - return render(request, "login.html") | 36 | + # res=JsonResponse({'token': token.key}) |
24 | -@csrf_exempt | 37 | + temp=(request.COOKIES['sessionid']) |
25 | -def login(request): | 38 | + # print(request.COOKIES['sessionid']) |
26 | - if request.user.is_authenticated: | 39 | + # response = HttpResponse('blah') |
27 | - raise PermissionDenied | 40 | + # response.set_cookie(key='access_token',value=temp, max_age=None) |
28 | - else: | 41 | + # res.set_cookie('access_token', |
29 | - if request.method == "POST": | 42 | + response =redirect("http://54.180.112.94:3001/",cookies=temp) |
30 | - data=request.POST | ||
31 | - if not all(i in data for i in ('username', 'password')): | ||
32 | - return render(request, "login.html", { | ||
33 | - "message": "아이디와 비밀번호를 입력해 주세요" | ||
34 | - }) | ||
35 | - un = data['username'] | ||
36 | - pw = data['password'] | ||
37 | - user = authenticate(username=un, password=pw) | ||
38 | - if user is not None: | ||
39 | - auth = django.contrib.auth.login(request, user) | ||
40 | - hashcode = hashlib.md5(request.POST['password'].encode('utf-8')).hexdigest() | ||
41 | - cog = cognito.Cognito() | ||
42 | - cog.sign_in_admin(username=un, password=hashcode) | ||
43 | - return JsonResponse({'user':{ | ||
44 | - 'username' :un, | ||
45 | - 'password' :pw, | ||
46 | - }}, safe=False) | ||
47 | - else: | ||
48 | - return render(request, "login.html", { | ||
49 | - "message": "아이디와 비밀번호를 확인해 주세요" | ||
50 | - }) | ||
51 | - | ||
52 | - else: | ||
53 | 43 | ||
54 | - return render(request, "login.html") | 44 | + response.set_cookie('username',temp,max_age=1000) |
55 | -def logout(request): | 45 | + print(token.key) |
56 | - if request.user.is_authenticated: | 46 | + # return redirect('http://54.180.112.94:3001/') |
57 | - django.contrib.auth.logout(request) | 47 | + request.session['zzz']=token.key |
58 | - return redirect("/main") | 48 | + """ |
49 | + return JsonResponse({ | ||
50 | + 'token': token.key | ||
59 | 51 | ||
60 | -def register(request): | 52 | + }) |
61 | - Cog = cognito.Cognito() | 53 | + """ |
62 | - reg=views.FileView() | 54 | + return response |
63 | - if request.user.is_authenticated: raise PermissionDenied | 55 | + |
64 | - if request.method == "POST": | 56 | +class GoogleLogin(SocialLoginView): |
65 | - require_keys = ('username', 'password', 'first_name', 'last_name', 'email') | 57 | + adapter_class=GoogleOAuth2Adapter |
66 | - if all(i in request.POST for i in require_keys): | 58 | +class LoginAPI(generics.GenericAPIView): |
67 | - if User.objects.filter(username=request.POST['username']).count(): | 59 | + # field : username, password |
68 | - return render(request, 'register.html', { | 60 | + serializer_class = LoginSerializer |
69 | - "message": 'alreadt exist username!' | 61 | + client_class=OAuth2Client |
70 | - }) | 62 | + print(client_class) |
71 | - if User.objects.filter(email=request.POST['email']).count(): | 63 | + def post(self, request, *args, **kwargs): |
72 | - return render(request, 'register.html', { | 64 | + print('login request가 들어왔으면 말좀 해줘', request.data) |
73 | - "message": 'alreadt exist email!' | 65 | + serializer = self.get_serializer(data=request.data) |
74 | - }) | 66 | + serializer.is_valid(raise_exception=True) |
75 | - userobj = User.objects.create_user( | 67 | + user = serializer.validated_data # complex type data |
76 | - username=request.POST['username'], | 68 | + print(user.username) |
77 | - password=request.POST['password'], | 69 | + token, created = Token.objects.get_or_create(user=user) |
78 | - first_name=request.POST['first_name'], | 70 | + return Response({ |
79 | - last_name=request.POST['last_name'], | 71 | + 'user': UserSerializer( |
80 | - email=request.POST['email'] | 72 | + user, context = self.get_serializer_context() |
81 | - ) | 73 | + ).data, |
82 | - hashcode = hashlib.md5(request.POST['password'].encode('utf-8')).hexdigest() | 74 | + 'token': token.key |
83 | - Cog.sign_up( | ||
84 | - username=request.POST['username'], | ||
85 | - password=hashcode, | ||
86 | - UserAttributes=[ | ||
87 | - { | ||
88 | - 'Name' : 'email', | ||
89 | - 'Value' : request.POST['email'], | ||
90 | - }, | ||
91 | - { | ||
92 | - 'Name' : 'family_name', | ||
93 | - 'Value': request.POST['first_name'], | ||
94 | - }, | ||
95 | - { | ||
96 | - 'Name' : 'given_name', | ||
97 | - 'Value': request.POST['last_name'], | ||
98 | - }, | ||
99 | - ]) | ||
100 | - Cog.confirm_sign_up(username=request.POST['username']); | ||
101 | - print(reg.create_bucket(request)) | ||
102 | - return redirect('/main') | ||
103 | - else: | ||
104 | - return render(request, 'register.html', { | ||
105 | - "message": 'error.' | ||
106 | - }) | ||
107 | - else: | ||
108 | - return render(request, 'register.html') | ||
109 | - | ||
110 | -def delete(request): | ||
111 | 75 | ||
112 | - if request.user.is_authenticated: | 76 | + }) |
113 | 77 | ||
114 | - if request.method == 'POST': | 78 | +class SignUpAPI(generics.GenericAPIView): |
79 | + serializer_class = SignUpSerializer | ||
80 | + def post(self, req, *args, **kwargs): | ||
81 | + Cog = cognito.Cognito() | ||
82 | + reg=views.FileView() | ||
83 | + print(req.data) | ||
84 | + serializer = self.get_serializer(data = req.data) | ||
85 | + hashcode = hashlib.md5(req.data['password'].encode('utf-8')).hexdigest() | ||
86 | + Cog.sign_up( | ||
87 | + username=req.data['username'], | ||
88 | + password=hashcode, | ||
89 | + UserAttributes=[ | ||
90 | + { | ||
91 | + 'Name' : 'email', | ||
92 | + 'Value' : req.data['email'], | ||
93 | + }, | ||
94 | + ]) | ||
95 | + Cog.confirm_sign_up(username=req.data['username']) | ||
96 | + serializer.is_valid(raise_exception=True) | ||
97 | + user = serializer.save() | ||
98 | + print(user) | ||
99 | + reg.create_bucket(req) | ||
100 | + token, created = Token.objects.get_or_create(user=user) | ||
101 | + return Response({ | ||
102 | + 'user': UserSerializer( | ||
103 | + user, context=self.get_serializer_context()).data, | ||
104 | + 'token': token.key | ||
105 | + }) | ||
106 | +class UserAPI(generics.RetrieveAPIView): | ||
107 | + permission_classes = [ | ||
108 | + permissions.IsAuthenticated, | ||
109 | + ] | ||
110 | + serializer_class = UserSerializer | ||
111 | + def get_object(self): | ||
112 | + print('Load Me 인증 성공', self.request.user) | ||
113 | + user = UserSerializer(self.request.user).data | ||
114 | + return self.request.user | ||
115 | 115 | ||
116 | - request.user.delete() | ||
117 | 116 | ||
118 | - return redirect('/main') | ||
119 | - else: | ||
120 | - return rendet(request,'delete.html',{ | ||
121 | - "message": 'login required!' | ||
122 | - }) | ||
123 | - return render(request, 'delete.html') | ... | ... |
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
... | @@ -50,7 +50,7 @@ class FileView(View): | ... | @@ -50,7 +50,7 @@ class FileView(View): |
50 | """ | 50 | """ |
51 | bucket=self.s3_client.create_bucket( | 51 | bucket=self.s3_client.create_bucket( |
52 | ACL='public-read-write', | 52 | ACL='public-read-write', |
53 | - Bucket=request.POST['username'], | 53 | + Bucket=request.data['username'], |
54 | CreateBucketConfiguration={ | 54 | CreateBucketConfiguration={ |
55 | 'LocationConstraint':'ap-northeast-2'}, | 55 | 'LocationConstraint':'ap-northeast-2'}, |
56 | ) | 56 | ) | ... | ... |
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
... | @@ -44,7 +44,9 @@ INSTALLED_APPS = [ | ... | @@ -44,7 +44,9 @@ INSTALLED_APPS = [ |
44 | 'blog.apps.BlogConfig', | 44 | 'blog.apps.BlogConfig', |
45 | 'corsheaders', | 45 | 'corsheaders', |
46 | 'rest_framework', | 46 | 'rest_framework', |
47 | + 'knox', | ||
47 | 'django.contrib.sites', | 48 | 'django.contrib.sites', |
49 | + 'rest_framework.authtoken', | ||
48 | 'cloud', | 50 | 'cloud', |
49 | # allauth | 51 | # allauth |
50 | 'allauth', | 52 | 'allauth', |
... | @@ -53,6 +55,7 @@ INSTALLED_APPS = [ | ... | @@ -53,6 +55,7 @@ INSTALLED_APPS = [ |
53 | # provider | 55 | # provider |
54 | 'allauth.socialaccount.providers.naver', | 56 | 'allauth.socialaccount.providers.naver', |
55 | 'allauth.socialaccount.providers.google', | 57 | 'allauth.socialaccount.providers.google', |
58 | + 'rest_auth.registration', | ||
56 | ] | 59 | ] |
57 | 60 | ||
58 | MIDDLEWARE = [ | 61 | MIDDLEWARE = [ |
... | @@ -69,15 +72,13 @@ MIDDLEWARE = [ | ... | @@ -69,15 +72,13 @@ MIDDLEWARE = [ |
69 | ] | 72 | ] |
70 | CORS_ORIGIN_ALLOWED_ALL = True | 73 | CORS_ORIGIN_ALLOWED_ALL = True |
71 | CORS_ALLOW_CREDENTIALS = True | 74 | CORS_ALLOW_CREDENTIALS = True |
72 | -""" | ||
73 | CORS_ORIGIN_WHITELIST = [ | 75 | CORS_ORIGIN_WHITELIST = [ |
74 | - | 76 | + 'http://0.0.0.0:3001', |
75 | -'http://localhost:3001/', | 77 | + 'http://54.180.112.94:3001', |
76 | - | 78 | + 'http://127.0.0.1:3001', |
77 | -'http://127.0.0.1:3001/', | 79 | + 'http://localhost:3001', |
78 | - | 80 | + 'http://172.31.39.245:3001', |
79 | ] | 81 | ] |
80 | -""" | ||
81 | ROOT_URLCONF = 'khuloud.urls' | 82 | ROOT_URLCONF = 'khuloud.urls' |
82 | 83 | ||
83 | TEMPLATES = [ | 84 | TEMPLATES = [ |
... | @@ -141,14 +142,31 @@ USE_I18N = True | ... | @@ -141,14 +142,31 @@ USE_I18N = True |
141 | USE_L10N = True | 142 | USE_L10N = True |
142 | 143 | ||
143 | USE_TZ = True | 144 | USE_TZ = True |
144 | - | 145 | +REST_FRAMEWORK = { |
146 | + # 권한 인증 | ||
147 | + 'DEFAULT_AUTHENTICATION_CLASSES': ( | ||
148 | + 'rest_framework.authentication.TokenAuthentication', | ||
149 | + # 'rest_framework.authentication.SessionAuthentication', | ||
150 | + ), | ||
151 | +} | ||
152 | +SOCIALACCOUNT_PROVIDERS = { | ||
153 | + 'google': { | ||
154 | + 'SCOPE': [ | ||
155 | + 'profile', | ||
156 | + 'email', | ||
157 | + ], | ||
158 | + 'AUTH_PARAMS': { | ||
159 | + 'access_type': 'online', | ||
160 | + } | ||
161 | + } | ||
162 | +} | ||
145 | 163 | ||
146 | # Static files (CSS, JavaScript, Images) | 164 | # Static files (CSS, JavaScript, Images) |
147 | # https://docs.djangoproject.com/en/1.11/howto/static-files/ | 165 | # https://docs.djangoproject.com/en/1.11/howto/static-files/ |
148 | AUTHENTICATION_BACKENDS = ( | 166 | AUTHENTICATION_BACKENDS = ( |
149 | 'django.contrib.auth.backends.ModelBackend',#Needed to login by username in Django admin, regardless of 'allauth' | 167 | 'django.contrib.auth.backends.ModelBackend',#Needed to login by username in Django admin, regardless of 'allauth' |
150 | 'allauth.account.auth_backends.AuthenticationBackend',#'allauth' specific authentication method, such as login by e-mail | 168 | 'allauth.account.auth_backends.AuthenticationBackend',#'allauth' specific authentication method, such as login by e-mail |
151 | - | 169 | + 'django.contrib.auth.backends.ModelBackend', |
152 | ) | 170 | ) |
153 | STATIC_URL = '/static/' | 171 | STATIC_URL = '/static/' |
154 | SITE_ID = 1 | 172 | SITE_ID = 1 | ... | ... |
... | @@ -21,11 +21,10 @@ from django.conf.urls import include, url | ... | @@ -21,11 +21,10 @@ from django.conf.urls import include, url |
21 | from django.urls import path, include | 21 | from django.urls import path, include |
22 | urlpatterns = [ | 22 | urlpatterns = [ |
23 | url(r'^admin/', admin.site.urls), | 23 | url(r'^admin/', admin.site.urls), |
24 | - url('main/',blog.views.main, name='main'), | 24 | + path('',include('blog.urls')), |
25 | - url(r'^login/', blog.views.login, name='login'), | ||
26 | - url(r'^logout/', blog.views.logout, name='logout'), | ||
27 | - url(r'^register/', blog.views.register, name='register'), | ||
28 | # url(r'^delete/',blog.views.delete, name='delete'), | 25 | # url(r'^delete/',blog.views.delete, name='delete'), |
29 | url(r'^accounts/', include('allauth.urls')), | 26 | url(r'^accounts/', include('allauth.urls')), |
30 | - path('cloud/',include('cloud.urls')) | 27 | + path('cloud/',include('cloud.urls')), |
28 | + url(r'^rest-auth/', include('rest_auth.urls')), | ||
29 | + url(r'^rest-auth/registration/', include('rest_auth.registration.urls')) | ||
31 | ]+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) | 30 | ]+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) | ... | ... |
frontend/.editorconfig
0 → 100644
frontend/.gitignore
0 → 100644
1 | +# Created by .ignore support plugin (hsz.mobi) | ||
2 | +### Node template | ||
3 | +# Logs | ||
4 | +/logs | ||
5 | +*.log | ||
6 | +npm-debug.log* | ||
7 | +yarn-debug.log* | ||
8 | +yarn-error.log* | ||
9 | + | ||
10 | +# Runtime data | ||
11 | +pids | ||
12 | +*.pid | ||
13 | +*.seed | ||
14 | +*.pid.lock | ||
15 | + | ||
16 | +# Directory for instrumented libs generated by jscoverage/JSCover | ||
17 | +lib-cov | ||
18 | + | ||
19 | +# Coverage directory used by tools like istanbul | ||
20 | +coverage | ||
21 | + | ||
22 | +# nyc test coverage | ||
23 | +.nyc_output | ||
24 | + | ||
25 | +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
26 | +.grunt | ||
27 | + | ||
28 | +# Bower dependency directory (https://bower.io/) | ||
29 | +bower_components | ||
30 | + | ||
31 | +# node-waf configuration | ||
32 | +.lock-wscript | ||
33 | + | ||
34 | +# Compiled binary addons (https://nodejs.org/api/addons.html) | ||
35 | +build/Release | ||
36 | + | ||
37 | +# Dependency directories | ||
38 | +node_modules/ | ||
39 | +jspm_packages/ | ||
40 | + | ||
41 | +# TypeScript v1 declaration files | ||
42 | +typings/ | ||
43 | + | ||
44 | +# Optional npm cache directory | ||
45 | +.npm | ||
46 | + | ||
47 | +# Optional eslint cache | ||
48 | +.eslintcache | ||
49 | + | ||
50 | +# Optional REPL history | ||
51 | +.node_repl_history | ||
52 | + | ||
53 | +# Output of 'npm pack' | ||
54 | +*.tgz | ||
55 | + | ||
56 | +# Yarn Integrity file | ||
57 | +.yarn-integrity | ||
58 | + | ||
59 | +# dotenv environment variables file | ||
60 | +.env | ||
61 | + | ||
62 | +# parcel-bundler cache (https://parceljs.org/) | ||
63 | +.cache | ||
64 | + | ||
65 | +# next.js build output | ||
66 | +.next | ||
67 | + | ||
68 | +# nuxt.js build output | ||
69 | +.nuxt | ||
70 | + | ||
71 | +# Nuxt generate | ||
72 | +dist | ||
73 | + | ||
74 | +# vuepress build output | ||
75 | +.vuepress/dist | ||
76 | + | ||
77 | +# Serverless directories | ||
78 | +.serverless | ||
79 | + | ||
80 | +# IDE / Editor | ||
81 | +.idea | ||
82 | + | ||
83 | +# Service worker | ||
84 | +sw.* | ||
85 | + | ||
86 | +# macOS | ||
87 | +.DS_Store | ||
88 | + | ||
89 | +# Vim swap files | ||
90 | +*.swp |
frontend/README.md
0 → 100644
1 | +# frontend | ||
2 | + | ||
3 | +> Khuloud Nuxt.js project | ||
4 | + | ||
5 | +## Build Setup | ||
6 | + | ||
7 | +node version: v12.16.0 | ||
8 | +npm version: 6.13.4 | ||
9 | + | ||
10 | + | ||
11 | +#### frontend 실행방법 | ||
12 | +```bash | ||
13 | + | ||
14 | +# install dependencies | ||
15 | +# frontend 폴더 내부에서 해당 명령어를 실행하면 package.json에 올려놓았던 모듈 설치 | ||
16 | +$ cd frontend/ | ||
17 | +$ npm install | ||
18 | + | ||
19 | +# run nuxt project | ||
20 | +# load http://localhost:3001 | ||
21 | +$ npm run start | ||
22 | + | ||
23 | +# django project | ||
24 | +$ cd user_server | ||
25 | +$ python manage.py runserver | ||
26 | + | ||
27 | +``` | ||
28 | + | ||
29 | +#### django server와 통신하는 부분 | ||
30 | +```bash | ||
31 | +# frontend/store/user.js | ||
32 | +this.$axios.get('본인이 만든 장고 url', withCredentials: true); | ||
33 | +this.$axios.post('본인이 만든 장고 url',{json 데이터}, withCredentials: true); | ||
34 | + | ||
35 | + | ||
36 | +## 현재 만든 frontend는 user_server django 파일로 요청이 가게 했습니다. | ||
37 | +``` |
frontend/assets/README.md
0 → 100644
1 | +# ASSETS | ||
2 | + | ||
3 | +**This directory is not required, you can delete it if you don't want to use it.** | ||
4 | + | ||
5 | +This directory contains your un-compiled assets such as LESS, SASS, or JavaScript. | ||
6 | + | ||
7 | +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked). |
frontend/assets/variables.scss
0 → 100644
frontend/components/ButtonIconVisibility.vue
0 → 100644
1 | +<template> | ||
2 | + <div> | ||
3 | + <v-btn class="pink white--text">click me</v-btn> | ||
4 | + <v-btn depressed class="pink">click me</v-btn> | ||
5 | + <v-btn flat class="pink">click me</v-btn> | ||
6 | + | ||
7 | + <v-btn depressed class="pink white--text"> | ||
8 | + <v-icon left>email</v-icon> | ||
9 | + <span>email me</span> | ||
10 | + </v-btn> | ||
11 | + | ||
12 | + <v-btn depressed small class="pink white--text"> | ||
13 | + <v-icon left small>email</v-icon> | ||
14 | + <span>email me</span> | ||
15 | + </v-btn> | ||
16 | + | ||
17 | + <v-btn fab small dark class="purple"> | ||
18 | + <v-icon>favorite</v-icon> | ||
19 | + </v-btn> | ||
20 | + | ||
21 | + | ||
22 | + <h1>HomePage</h1> | ||
23 | + <v-btn class="hidden-md-and-down">click me</v-btn> | ||
24 | + <v-btn class="hidden-md-and-up">click me</v-btn> | ||
25 | + <v-btn class="hidden-sm-only">click me</v-btn> | ||
26 | + | ||
27 | + </div> | ||
28 | +</template> | ||
29 | + | ||
30 | +<script> | ||
31 | + export default { | ||
32 | + name: "ButtonIconVisibility" | ||
33 | + } | ||
34 | +</script> | ||
35 | + | ||
36 | +<style scoped> | ||
37 | + | ||
38 | +</style> |
frontend/components/LoginComponent.vue
0 → 100644
1 | +<template> | ||
2 | + <div> | ||
3 | + <v-row | ||
4 | + align="center" | ||
5 | + justify="center"> | ||
6 | + <v-col | ||
7 | + cols="12" | ||
8 | + sm="8" | ||
9 | + md="4" | ||
10 | + > | ||
11 | + <v-card> | ||
12 | + <v-form v-model="valid" @submit.prevent="login"> | ||
13 | + <v-card-text> | ||
14 | + <v-text-field | ||
15 | + v-model="username" | ||
16 | + :rules="[rules.username]" | ||
17 | + label="username" | ||
18 | + prepend-icon="person"> | ||
19 | + </v-text-field> | ||
20 | + <v-text-field | ||
21 | + v-model="password" | ||
22 | + :rules="[rules.password]" | ||
23 | + type="password" | ||
24 | + label="password" | ||
25 | + prepend-icon="lock"> | ||
26 | + </v-text-field> | ||
27 | + </v-card-text> | ||
28 | + <v-card-actions> | ||
29 | + <v-spacer/> | ||
30 | + <v-btn | ||
31 | + color="yellow" | ||
32 | + type="submit"> | ||
33 | + 로그인 | ||
34 | + </v-btn> | ||
35 | + </v-card-actions> | ||
36 | + </v-form> | ||
37 | + </v-card> | ||
38 | + </v-col> | ||
39 | + </v-row> | ||
40 | + </div> | ||
41 | +</template> | ||
42 | + | ||
43 | + | ||
44 | +<script> | ||
45 | + export default { | ||
46 | + name: "loginComponent", | ||
47 | + data() { | ||
48 | + return { | ||
49 | + valid: false, | ||
50 | + tryLogin: true, | ||
51 | + username: '', | ||
52 | + password: '', | ||
53 | + rules: { | ||
54 | + username: v => !!v || 'username is required', | ||
55 | + password: v => !!v || 'password is required', | ||
56 | + } | ||
57 | + } | ||
58 | + }, | ||
59 | + methods: { | ||
60 | + async login() { | ||
61 | + try { | ||
62 | + console.log('login Method'); | ||
63 | + //$store.dispatch -> action의 login 함수를 불러 쓸 수 있음 | ||
64 | + await this.$store.dispatch('user/login', { | ||
65 | + username: this.username, | ||
66 | + password: this.password | ||
67 | + }); | ||
68 | + await this.$router.replace('/'); | ||
69 | + } catch (e) { | ||
70 | + console.error(e); | ||
71 | + } | ||
72 | + }, | ||
73 | + changeTryLogin() { | ||
74 | + this.tryLogin = !this.tryLogin; | ||
75 | + } | ||
76 | + } | ||
77 | + } | ||
78 | +</script> |
frontend/components/Logo.vue
0 → 100644
1 | +<template> | ||
2 | + <div class="VueToNuxtLogo"> | ||
3 | + <div class="Triangle Triangle--two" /> | ||
4 | + <div class="Triangle Triangle--one" /> | ||
5 | + <div class="Triangle Triangle--three" /> | ||
6 | + <div class="Triangle Triangle--four" /> | ||
7 | + </div> | ||
8 | +</template> | ||
9 | + | ||
10 | +<style> | ||
11 | +.VueToNuxtLogo { | ||
12 | + display: inline-block; | ||
13 | + animation: turn 2s linear forwards 1s; | ||
14 | + transform: rotateX(180deg); | ||
15 | + position: relative; | ||
16 | + overflow: hidden; | ||
17 | + height: 180px; | ||
18 | + width: 245px; | ||
19 | +} | ||
20 | + | ||
21 | +.Triangle { | ||
22 | + position: absolute; | ||
23 | + top: 0; | ||
24 | + left: 0; | ||
25 | + width: 0; | ||
26 | + height: 0; | ||
27 | +} | ||
28 | + | ||
29 | +.Triangle--one { | ||
30 | + border-left: 105px solid transparent; | ||
31 | + border-right: 105px solid transparent; | ||
32 | + border-bottom: 180px solid #41b883; | ||
33 | +} | ||
34 | + | ||
35 | +.Triangle--two { | ||
36 | + top: 30px; | ||
37 | + left: 35px; | ||
38 | + animation: goright 0.5s linear forwards 3.5s; | ||
39 | + border-left: 87.5px solid transparent; | ||
40 | + border-right: 87.5px solid transparent; | ||
41 | + border-bottom: 150px solid #3b8070; | ||
42 | +} | ||
43 | + | ||
44 | +.Triangle--three { | ||
45 | + top: 60px; | ||
46 | + left: 35px; | ||
47 | + animation: goright 0.5s linear forwards 3.5s; | ||
48 | + border-left: 70px solid transparent; | ||
49 | + border-right: 70px solid transparent; | ||
50 | + border-bottom: 120px solid #35495e; | ||
51 | +} | ||
52 | + | ||
53 | +.Triangle--four { | ||
54 | + top: 120px; | ||
55 | + left: 70px; | ||
56 | + animation: godown 0.5s linear forwards 3s; | ||
57 | + border-left: 35px solid transparent; | ||
58 | + border-right: 35px solid transparent; | ||
59 | + border-bottom: 60px solid #fff; | ||
60 | +} | ||
61 | + | ||
62 | +@keyframes turn { | ||
63 | + 100% { | ||
64 | + transform: rotateX(0deg); | ||
65 | + } | ||
66 | +} | ||
67 | + | ||
68 | +@keyframes godown { | ||
69 | + 100% { | ||
70 | + top: 180px; | ||
71 | + } | ||
72 | +} | ||
73 | + | ||
74 | +@keyframes goright { | ||
75 | + 100% { | ||
76 | + left: 70px; | ||
77 | + } | ||
78 | +} | ||
79 | +</style> | ||
80 | + |
frontend/components/Navbar.vue
0 → 100644
1 | +<template> | ||
2 | + <nav> | ||
3 | + <v-toolbar flat app> | ||
4 | + <v-toolbar-side-icon class="grey--text" @click="drawer = !drawer">nav</v-toolbar-side-icon> | ||
5 | + <v-toolbar-title class="text-uppercase grey--text"> | ||
6 | + <span class="font-weight-light">Todo</span> | ||
7 | + <span>Ninja</span> | ||
8 | + </v-toolbar-title> | ||
9 | + <v-spacer/> | ||
10 | + <v-btn flat fab small color="grey"> | ||
11 | + <v-icon small>exit_to_app</v-icon> | ||
12 | + </v-btn> | ||
13 | + </v-toolbar> | ||
14 | + | ||
15 | + <!-- color success(녹색), primary(파랑), warning(빨강)--> | ||
16 | + <v-navigation-drawer app v-model="drawer" class="success"> | ||
17 | + <v-list> | ||
18 | + <v-list-tile v-for="link in links" :key="link.text" router :to="link.route"> | ||
19 | + <v-list-tile-action> | ||
20 | + <v-icon class="white--text">{{link.icon}}</v-icon> | ||
21 | + </v-list-tile-action> | ||
22 | + <v-list-tile-content> | ||
23 | + <v-list-tile-title class="white--text">{{link.text}}</v-list-tile-title> | ||
24 | + </v-list-tile-content> | ||
25 | + </v-list-tile> | ||
26 | + </v-list> | ||
27 | + </v-navigation-drawer> | ||
28 | + </nav> | ||
29 | +</template> | ||
30 | +<script> | ||
31 | + import inspire from "../pages/inspire"; | ||
32 | + import index from "../pages/index"; | ||
33 | + | ||
34 | + export default { | ||
35 | + name: "NavBar", | ||
36 | + data() { | ||
37 | + return { | ||
38 | + drawer: false, | ||
39 | + links: [ | ||
40 | + {icon: 'dashboard', text: 'Dashboard', route: '/'}, | ||
41 | + {icon: 'folder', text: 'MyProfile', route: '/inspire'}, | ||
42 | + {icon: 'person', text: 'Team', route: '/'}, | ||
43 | + ] | ||
44 | + } | ||
45 | + } | ||
46 | + } | ||
47 | +</script> | ||
48 | + | ||
49 | +<style scoped> | ||
50 | + | ||
51 | +</style> |
frontend/components/PaddingMarginGrid.vue
0 → 100644
1 | +<template> | ||
2 | + <div class="mx-4 mb-4"> | ||
3 | + <h1 class="subheading grey--text">Team</h1> | ||
4 | + | ||
5 | + <v-container fluid class="my-5"> | ||
6 | + <v-layout row wrap> | ||
7 | + <v-flex xs12 md6> | ||
8 | + <v-btn outline block class="primary">1</v-btn> | ||
9 | + </v-flex> | ||
10 | + <v-flex xs4 md2> | ||
11 | + <v-btn outline block class="primary">2</v-btn> | ||
12 | + </v-flex> | ||
13 | + <v-flex xs4 md2> | ||
14 | + <v-btn outline block class="primary">2</v-btn> | ||
15 | + </v-flex> | ||
16 | + <v-flex xs4 md2> | ||
17 | + <v-btn outline block class="primary">2</v-btn> | ||
18 | + </v-flex> | ||
19 | + </v-layout> | ||
20 | + | ||
21 | + <!-- justify-end, center, space-around--> | ||
22 | + | ||
23 | + <v-layout row wrap justify-end> | ||
24 | + <v-flex xs4 md3> | ||
25 | + <v-btn outline block class="success">1</v-btn> | ||
26 | + </v-flex> | ||
27 | + <v-flex xs4 md3> | ||
28 | + <v-btn outline block class="success">2</v-btn> | ||
29 | + </v-flex> | ||
30 | + </v-layout> | ||
31 | + </v-container> | ||
32 | + | ||
33 | + | ||
34 | + <v-container class="my-5"> | ||
35 | + | ||
36 | + <v-layout row class="mb-3"> | ||
37 | + <v-tooltip top> | ||
38 | + <template v-slot:activator="{ on }"> | ||
39 | + <v-btn small flat color="grey" @click="sortBy('title')" v-on="on"> | ||
40 | + <v-icon left small>folder</v-icon> | ||
41 | + <span class="caption text-lowercase">By project name</span> | ||
42 | + </v-btn> | ||
43 | + </template> | ||
44 | + <span>Sort projects by project name</span> | ||
45 | + </v-tooltip> | ||
46 | + | ||
47 | + <v-tooltip top> | ||
48 | + <template v-slot:activator="{ on }"> | ||
49 | + <v-btn small flat color="grey" @click="sortBy('person')" v-on="on"> | ||
50 | + <v-icon left small>person</v-icon> | ||
51 | + <span class="caption text-lowercase">By person</span> | ||
52 | + </v-btn> | ||
53 | + </template> | ||
54 | + <span>Sort projects by person</span> | ||
55 | + </v-tooltip> | ||
56 | + </v-layout> | ||
57 | + | ||
58 | + | ||
59 | + <v-card flat class="pa-3" v-for="project in projects" :key="project.title"> | ||
60 | + <v-layout row wrap :class="`pa-3 project ${project.status}`"> | ||
61 | + <v-flex xs12 md6> | ||
62 | + <div class="caption grey--text">project title</div> | ||
63 | + <div>{{project.title}}</div> | ||
64 | + </v-flex> | ||
65 | + <v-flex xs4 md2> | ||
66 | + <div class="caption grey--text">Person</div> | ||
67 | + <div>{{project.person}}</div> | ||
68 | + </v-flex> | ||
69 | + <v-flex xs4 md2> | ||
70 | + <div class="caption grey--text">Due by</div> | ||
71 | + <div>{{project.due}}</div> | ||
72 | + </v-flex> | ||
73 | + <v-flex xs4 md2> | ||
74 | + <v-chip small :class="`${project.status} white--text caption my-2`">{{project.status}}</v-chip> | ||
75 | + </v-flex> | ||
76 | + </v-layout> | ||
77 | + </v-card> | ||
78 | + </v-container> | ||
79 | + </div> | ||
80 | +</template> | ||
81 | + | ||
82 | +<script> | ||
83 | + export default { | ||
84 | + name: "PaddingMarginGrid", | ||
85 | + data() { | ||
86 | + return { | ||
87 | + projects: [ | ||
88 | + {title: 'Design a new website', person: 'The Net Ninja', due: '1st Jan 2019', status: 'ongoing'}, | ||
89 | + {title: 'Write a new website', person: 'Net Ninja', due: '1st Jan 2019', status: 'complete'}, | ||
90 | + {title: 'Create a new website', person: 'Ninja', due: '1st Jan 2019', status: 'ongoing'}, | ||
91 | + {title: 'Update a new website', person: 'tjddus', due: '1st Jan 2019', status: 'overdue'} | ||
92 | + ] | ||
93 | + } | ||
94 | + }, | ||
95 | + methods: { | ||
96 | + sortBy(props) { | ||
97 | + this.projects.sort((a, b) => a[props] < b[props] ? -1 : 1); | ||
98 | + } | ||
99 | + } | ||
100 | + } | ||
101 | +</script> | ||
102 | + | ||
103 | +<style scoped> | ||
104 | + .project.complete { | ||
105 | + border-left: 4px solid #3cd1c2; | ||
106 | + } | ||
107 | + | ||
108 | + .project.ongoing { | ||
109 | + border-left: 4px solid orange; | ||
110 | + } | ||
111 | + | ||
112 | + .project.overdue { | ||
113 | + border-left: 4px solid tomato; | ||
114 | + } | ||
115 | + | ||
116 | + .v-chip.complete { | ||
117 | + background: #3cd1c2; | ||
118 | + } | ||
119 | + | ||
120 | + .v-chip.ongoing { | ||
121 | + background: orange; | ||
122 | + } | ||
123 | + | ||
124 | + .v-chip.overdue { | ||
125 | + background: tomato; | ||
126 | + } | ||
127 | +</style> |
frontend/components/README.md
0 → 100644
frontend/components/SignUpComponent.vue
0 → 100644
1 | +<template> | ||
2 | + <div> | ||
3 | + <v-row | ||
4 | + align="center" | ||
5 | + justify="center" | ||
6 | + > | ||
7 | + <v-col | ||
8 | + cols="12" | ||
9 | + sm="8" | ||
10 | + md="4" | ||
11 | + > | ||
12 | + <v-card> | ||
13 | + <v-form v-model="valid" @submit.prevent="signUp"> | ||
14 | + <v-card-text> | ||
15 | + <v-text-field | ||
16 | + v-model="email" | ||
17 | + :rules="[rules.email]" | ||
18 | + prepend-icon="email" | ||
19 | + label="email"> | ||
20 | + </v-text-field> | ||
21 | + <v-text-field | ||
22 | + v-model="username" | ||
23 | + :rules="[rules.username]" | ||
24 | + prepend-icon="person" | ||
25 | + label="username"> | ||
26 | + </v-text-field> | ||
27 | + <v-text-field | ||
28 | + v-model="password" | ||
29 | + :rules="[rules.password]" | ||
30 | + prepend-icon="lock" | ||
31 | + type="password" | ||
32 | + label="password"> | ||
33 | + </v-text-field> | ||
34 | + <v-text-field | ||
35 | + v-model="checkpassword" | ||
36 | + :rules="[rules.checkpassword]" | ||
37 | + prepend-icon="lock" | ||
38 | + type="password" | ||
39 | + label="checkpassword"> | ||
40 | + </v-text-field> | ||
41 | + </v-card-text> | ||
42 | + <v-card-actions> | ||
43 | + <v-spacer/> | ||
44 | + <v-btn | ||
45 | + color="yellow" | ||
46 | + type="submit"> | ||
47 | + 회원가입 | ||
48 | + </v-btn> | ||
49 | + </v-card-actions> | ||
50 | + </v-form> | ||
51 | + </v-card> | ||
52 | + </v-col> | ||
53 | + </v-row> | ||
54 | + </div> | ||
55 | +</template> | ||
56 | + | ||
57 | +<script> | ||
58 | + export default { | ||
59 | + name: "SignUpComponent", | ||
60 | + data() { | ||
61 | + return { | ||
62 | + valid: false, | ||
63 | + email: '', | ||
64 | + name: '', | ||
65 | + password: '', | ||
66 | + checkpassword: '', | ||
67 | + rules: { | ||
68 | + email: v => (v || '').match(/@/) || 'Please enter a valid email', | ||
69 | + username: v => !!v || 'usrename is required', | ||
70 | + password: v => !!v || 'password is required', | ||
71 | + checkpassword: v => v == this.password || 'checkpassword is incorrect' | ||
72 | + } | ||
73 | + } | ||
74 | + }, | ||
75 | + methods: { | ||
76 | + async signUp() { | ||
77 | + try { | ||
78 | + console.log('signUp Method'); | ||
79 | + //$store.dispatch -> action의 signUp 함수를 불러올 수 있음 | ||
80 | + await this.$store.dispatch('user/signUp', { | ||
81 | + email: this.email, | ||
82 | + username: this.username, | ||
83 | + password: this.password | ||
84 | + }); | ||
85 | + await this.$router.replace('/'); | ||
86 | + } catch (e) { | ||
87 | + console.error(e); | ||
88 | + } | ||
89 | + } | ||
90 | + } | ||
91 | + } | ||
92 | +</script> | ||
93 | + | ||
94 | +<style scoped> | ||
95 | + | ||
96 | +</style> | ||
97 | + | ||
98 | + |
frontend/components/VuetifyLogo.vue
0 → 100644
1 | +<template> | ||
2 | + <img | ||
3 | + class="VuetifyLogo" | ||
4 | + alt="Vuetify Logo" | ||
5 | + src="/vuetify-logo.svg" | ||
6 | + > | ||
7 | +</template> | ||
8 | + | ||
9 | +<style> | ||
10 | +.VuetifyLogo { | ||
11 | + height:180px; | ||
12 | + width: 180px; | ||
13 | + transform: rotateY(560deg); | ||
14 | + animation: turn 3.5s ease-out forwards 1s; | ||
15 | +} | ||
16 | + | ||
17 | +@keyframes turn { | ||
18 | + 100% { | ||
19 | + transform: rotateY(0deg); | ||
20 | + } | ||
21 | +} | ||
22 | +</style> |
frontend/layouts/README.md
0 → 100644
frontend/layouts/default.vue
0 → 100644
1 | +<template> | ||
2 | + <v-app id="keep"> | ||
3 | + <v-app-bar | ||
4 | + app | ||
5 | + clipped-left | ||
6 | + color="amber" | ||
7 | + > | ||
8 | + <v-app-bar-nav-icon @click="drawer = !drawer"/> | ||
9 | + <span class="title ml-3 mr-5">KHUloud </span> | ||
10 | + <v-text-field | ||
11 | + solo-inverted | ||
12 | + flat | ||
13 | + hide-details | ||
14 | + label="Search" | ||
15 | + prepend-inner-icon="search" | ||
16 | + /> | ||
17 | + <v-spacer/> | ||
18 | + <v-btn | ||
19 | + icon | ||
20 | + to="/inspire"> | ||
21 | + <v-icon>account_circle</v-icon> | ||
22 | + </v-btn> | ||
23 | + </v-app-bar> | ||
24 | + | ||
25 | + <v-navigation-drawer | ||
26 | + v-model="drawer" | ||
27 | + app | ||
28 | + clipped | ||
29 | + color="grey lighten-4" | ||
30 | + > | ||
31 | + <v-list | ||
32 | + dense | ||
33 | + class="grey lighten-4" | ||
34 | + > | ||
35 | + <template v-for="(item, i) in items"> | ||
36 | + <v-row | ||
37 | + v-if="item.heading" | ||
38 | + :key="i" | ||
39 | + align="center" | ||
40 | + > | ||
41 | + <v-col cols="6"> | ||
42 | + <v-subheader v-if="item.heading"> | ||
43 | + {{ item.heading }} | ||
44 | + </v-subheader> | ||
45 | + </v-col> | ||
46 | + <v-col | ||
47 | + cols="6" | ||
48 | + class="text-right" | ||
49 | + > | ||
50 | + <v-btn | ||
51 | + small | ||
52 | + text | ||
53 | + >edit | ||
54 | + </v-btn> | ||
55 | + </v-col> | ||
56 | + </v-row> | ||
57 | + <v-divider | ||
58 | + v-else-if="item.divider" | ||
59 | + :key="i" | ||
60 | + dark | ||
61 | + class="my-4" | ||
62 | + /> | ||
63 | + <v-list-item | ||
64 | + v-else | ||
65 | + :key="i" | ||
66 | + link | ||
67 | + > | ||
68 | + <v-list-item-action> | ||
69 | + <v-icon>{{ item.icon }}</v-icon> | ||
70 | + </v-list-item-action> | ||
71 | + <v-list-item-content> | ||
72 | + <v-list-item-title class="grey--text"> | ||
73 | + {{ item.text }} | ||
74 | + </v-list-item-title> | ||
75 | + </v-list-item-content> | ||
76 | + </v-list-item> | ||
77 | + </template> | ||
78 | + </v-list> | ||
79 | + </v-navigation-drawer> | ||
80 | + | ||
81 | + <v-content> | ||
82 | + <nuxt/> | ||
83 | + </v-content> | ||
84 | + </v-app> | ||
85 | +</template> | ||
86 | + | ||
87 | +<script> | ||
88 | + import 'material-design-icons-iconfont/dist/material-design-icons.css' | ||
89 | + | ||
90 | + export default { | ||
91 | + props: { | ||
92 | + source: String, | ||
93 | + }, | ||
94 | + data: () => ({ | ||
95 | + drawer: false, | ||
96 | + items: [ | ||
97 | + {icon: 'lightbulb_outline', text: 'Notes'}, | ||
98 | + {icon: 'touch_app', text: 'Reminders'}, | ||
99 | + {divider: true}, | ||
100 | + {heading: 'Labels'}, | ||
101 | + {icon: 'add', text: 'Create new folder'}, | ||
102 | + {divider: true}, | ||
103 | + {icon: 'archive', text: 'Archive'}, | ||
104 | + {icon: 'delete', text: 'Trash'}, | ||
105 | + {divider: true}, | ||
106 | + {icon: 'settings', text: 'Settings'}, | ||
107 | + {icon: 'chat_bubble', text: 'Trash'}, | ||
108 | + {icon: 'help', text: 'Help'}, | ||
109 | + {icon: 'phonelink', text: 'App downloads'}, | ||
110 | + {icon: 'keyboard', text: 'Keyboard shortcuts'}, | ||
111 | + ], | ||
112 | + }), | ||
113 | + methods: { | ||
114 | + account() { | ||
115 | + this.$router.push('inspire'); | ||
116 | + } | ||
117 | + } | ||
118 | + } | ||
119 | +</script> | ||
120 | + | ||
121 | +<style> | ||
122 | + #keep .v-navigation-drawer__border { | ||
123 | + display: none | ||
124 | + } | ||
125 | +</style> |
frontend/layouts/error.vue
0 → 100644
1 | +<template> | ||
2 | + <v-app dark> | ||
3 | + <h1 v-if="error.statusCode === 404"> | ||
4 | + {{ pageNotFound }} | ||
5 | + </h1> | ||
6 | + <h1 v-else> | ||
7 | + {{ otherError }} | ||
8 | + </h1> | ||
9 | + <NuxtLink to="/"> | ||
10 | + Home page | ||
11 | + </NuxtLink> | ||
12 | + </v-app> | ||
13 | +</template> | ||
14 | + | ||
15 | +<script> | ||
16 | +export default { | ||
17 | + layout: 'empty', | ||
18 | + props: { | ||
19 | + error: { | ||
20 | + type: Object, | ||
21 | + default: null | ||
22 | + } | ||
23 | + }, | ||
24 | + data () { | ||
25 | + return { | ||
26 | + pageNotFound: '404 Not Found', | ||
27 | + otherError: 'An error occurred' | ||
28 | + } | ||
29 | + }, | ||
30 | + head () { | ||
31 | + const title = | ||
32 | + this.error.statusCode === 404 ? this.pageNotFound : this.otherError | ||
33 | + return { | ||
34 | + title | ||
35 | + } | ||
36 | + } | ||
37 | +} | ||
38 | +</script> | ||
39 | + | ||
40 | +<style scoped> | ||
41 | +h1 { | ||
42 | + font-size: 20px; | ||
43 | +} | ||
44 | +</style> |
frontend/middleware/README.md
0 → 100644
1 | +# MIDDLEWARE | ||
2 | + | ||
3 | +**This directory is not required, you can delete it if you don't want to use it.** | ||
4 | + | ||
5 | +This directory contains your application middleware. | ||
6 | +Middleware let you define custom functions that can be run before rendering either a page or a group of pages. | ||
7 | + | ||
8 | +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware). |
frontend/nuxt.config.js
0 → 100644
1 | +// import colors from 'vuetify/es5/util/colors' | ||
2 | +// | ||
3 | +// export default { | ||
4 | +// mode: 'universal', | ||
5 | +// /* | ||
6 | +// ** Headers of the page | ||
7 | +// */ | ||
8 | +// head: { | ||
9 | +// titleTemplate: '%s - ' + process.env.npm_package_name, | ||
10 | +// title: process.env.npm_package_name || '', | ||
11 | +// meta: [ | ||
12 | +// { charset: 'utf-8' }, | ||
13 | +// { name: 'viewport', content: 'width=device-width, initial-scale=1' }, | ||
14 | +// { hid: 'description', name: 'description', content: process.env.npm_package_description || '' } | ||
15 | +// ], | ||
16 | +// link: [ | ||
17 | +// { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' } | ||
18 | +// ] | ||
19 | +// }, | ||
20 | +// /* | ||
21 | +// ** Customize the progress-bar color | ||
22 | +// */ | ||
23 | +// loading: { color: '#fff' }, | ||
24 | +// /* | ||
25 | +// ** Global CSS | ||
26 | +// */ | ||
27 | +// css: [ | ||
28 | +// ], | ||
29 | +// /* | ||
30 | +// ** Plugins to load before mounting the App | ||
31 | +// */ | ||
32 | +// plugins: [ | ||
33 | +// ], | ||
34 | +// /* | ||
35 | +// ** Nuxt.js dev-modules | ||
36 | +// */ | ||
37 | +// buildModules: [ | ||
38 | +// '@nuxtjs/vuetify', | ||
39 | +// '@nuxtjs/moment', | ||
40 | +// ], | ||
41 | +// /* | ||
42 | +// ** Nuxt.js modules | ||
43 | +// */ | ||
44 | +// modules: [ | ||
45 | +// '@nuxtjs/axios', | ||
46 | +// '@nuxtjs/pwa' | ||
47 | +// ], | ||
48 | +// /* | ||
49 | +// ** Build configuration | ||
50 | +// */ | ||
51 | +// build: { | ||
52 | +// /* | ||
53 | +// ** You can extend webpack config here | ||
54 | +// */ | ||
55 | +// extend (config, ctx) { | ||
56 | +// } | ||
57 | +// } | ||
58 | +// } | ||
59 | + | ||
60 | + | ||
61 | +import webpack from 'webpack' | ||
62 | + | ||
63 | +module.exports = { | ||
64 | + | ||
65 | + server: { | ||
66 | + host: '0.0.0.0', | ||
67 | + port: 3001 | ||
68 | + }, | ||
69 | + head: { | ||
70 | + meta: [{ | ||
71 | + charset: 'utf-8', | ||
72 | + }, { | ||
73 | + name: 'viewport', | ||
74 | + content: 'width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no', | ||
75 | + }], | ||
76 | + cookie: {} | ||
77 | + }, | ||
78 | + modules: [ | ||
79 | + '@nuxtjs/axios', | ||
80 | + '@nuxtjs/pwa', | ||
81 | + ], | ||
82 | + buildModules: [ | ||
83 | + '@nuxtjs/vuetify', | ||
84 | + '@nuxtjs/moment', | ||
85 | + ], | ||
86 | + | ||
87 | + // pwa: { | ||
88 | + // icon: { | ||
89 | + // iconSrc: 'static/icon.png' | ||
90 | + // }, | ||
91 | + // manifest: { | ||
92 | + // name: 'node_express_study_final' | ||
93 | + // }, | ||
94 | + // workbox: { | ||
95 | + // dev: true, | ||
96 | + // runtimeCaching: [{ | ||
97 | + // urlPattern: 'http://localhost:4001/.*', | ||
98 | + // method: 'GET' | ||
99 | + // }, { | ||
100 | + // urlPattern: 'http://localhost:5001/.*', | ||
101 | + // method: 'GET' | ||
102 | + // }] | ||
103 | + // }, | ||
104 | + // } | ||
105 | +}; |
frontend/package-lock.json
0 → 100644
This diff could not be displayed because it is too large.
frontend/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "frontend", | ||
3 | + "scripts": { | ||
4 | + "start": "nuxt" | ||
5 | + }, | ||
6 | + "dependencies": { | ||
7 | + "@nuxtjs/axios": "^5.9.5", | ||
8 | + "@nuxtjs/moment": "^1.6.0", | ||
9 | + "@nuxtjs/pwa": "^3.0.0-beta.20", | ||
10 | + "@nuxtjs/vuetify": "^1.11.0", | ||
11 | + "jquery": "^3.4.1", | ||
12 | + "js-cookie": "^2.2.1", | ||
13 | + "loadsh": "0.0.4", | ||
14 | + "lodash.throttle": "^4.1.1", | ||
15 | + "material-design-icons-iconfont": "^5.0.1", | ||
16 | + "nuxt": "^2.11.0", | ||
17 | + "socket.io-client": "^2.3.0", | ||
18 | + "webpack": "^4.43.0" | ||
19 | + } | ||
20 | +} |
frontend/pages/README.md
0 → 100644
1 | +# PAGES | ||
2 | + | ||
3 | +This directory contains your Application Views and Routes. | ||
4 | +The framework reads all the `*.vue` files inside this directory and creates the router of your application. | ||
5 | + | ||
6 | +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing). |
frontend/pages/index.vue
0 → 100644
1 | +<template> | ||
2 | + <v-layout | ||
3 | + column | ||
4 | + justify-center | ||
5 | + align-center | ||
6 | + > | ||
7 | + <v-flex | ||
8 | + xs12 | ||
9 | + sm8 | ||
10 | + md1 | ||
11 | + > | ||
12 | + <div v-if="!me"> | ||
13 | + Do login | ||
14 | + </div> | ||
15 | + <div v-else> | ||
16 | + {{me.username}}님 환영합니다 | ||
17 | + <v-data-table | ||
18 | + :headers="headers" | ||
19 | + :items="files" | ||
20 | + :items-per-page="10" | ||
21 | + class="elevation-1" | ||
22 | + /> | ||
23 | + </div> | ||
24 | + </v-flex> | ||
25 | + </v-layout> | ||
26 | +</template> | ||
27 | + | ||
28 | +<script> | ||
29 | + import Navbar from "../components/Navbar"; | ||
30 | + | ||
31 | + export default { | ||
32 | + name: "home", | ||
33 | + components: {Navbar}, | ||
34 | + data() { | ||
35 | + return { | ||
36 | + headers: [ | ||
37 | + { | ||
38 | + text: '이름', | ||
39 | + }, { | ||
40 | + text: '수정한 날짜', | ||
41 | + }, { | ||
42 | + text: '공유', | ||
43 | + }, { | ||
44 | + text: '크기', | ||
45 | + } | ||
46 | + ], | ||
47 | + files: [] | ||
48 | + } | ||
49 | + }, | ||
50 | + computed: { | ||
51 | + me() { | ||
52 | + return this.$store.state.user.me; | ||
53 | + } | ||
54 | + } | ||
55 | + } | ||
56 | +</script> | ||
57 | + |
frontend/pages/inspire.vue
0 → 100644
1 | +<template> | ||
2 | + <v-layout> | ||
3 | + <v-flex class="text-center"> | ||
4 | + <div | ||
5 | + v-if="me"> | ||
6 | + <v-btn @click="logout">로그아웃</v-btn> | ||
7 | + </div> | ||
8 | + <div | ||
9 | + v-else> | ||
10 | + <div | ||
11 | + v-if="tryLogin"> | ||
12 | + <login-component/> | ||
13 | + <v-btn @click="changeTryLogin">회원가입</v-btn> | ||
14 | + </div> | ||
15 | + <div | ||
16 | + v-else> | ||
17 | + <sign-up-component/> | ||
18 | + <v-btn @click="changeTryLogin">로그인</v-btn> | ||
19 | + </div> | ||
20 | + </div> | ||
21 | + <v-btn @click="socialLogin">소셜로그인</v-btn> | ||
22 | + </v-flex> | ||
23 | + </v-layout> | ||
24 | +</template> | ||
25 | + | ||
26 | +<script> | ||
27 | + import LoginComponent from "../components/LoginComponent"; | ||
28 | + import SignUpComponent from "../components/SignUpComponent"; | ||
29 | + | ||
30 | + export default { | ||
31 | + data() { | ||
32 | + return { | ||
33 | + tryLogin: true, | ||
34 | + } | ||
35 | + }, | ||
36 | + computed: { | ||
37 | + me() { | ||
38 | + return this.$store.state.user.me | ||
39 | + } | ||
40 | + }, | ||
41 | + components: { | ||
42 | + LoginComponent, | ||
43 | + SignUpComponent, | ||
44 | + }, | ||
45 | + methods: { | ||
46 | + changeTryLogin() { | ||
47 | + this.tryLogin = !this.tryLogin | ||
48 | + }, | ||
49 | + async logout() { | ||
50 | + try { | ||
51 | + await this.$store.dispatch('user/logout'); | ||
52 | + await this.$router.replace('/'); | ||
53 | + } catch (e) { | ||
54 | + console.error(e); | ||
55 | + } | ||
56 | + }, | ||
57 | + async socialLogin(){ | ||
58 | + try{ | ||
59 | + if(process.client){ | ||
60 | + console.log('zzz') | ||
61 | + window.open('http://ec2-54-180-112-94.ap-northeast-2.compute.amazonaws.com:8080/accounts/google/login/') | ||
62 | + } | ||
63 | + console.log('z') | ||
64 | + await this.$store.dispatch('user/socialLogin'); | ||
65 | + await this.$router.replace('/'); | ||
66 | + }catch(e){ | ||
67 | + console.error(e); | ||
68 | + } | ||
69 | + }, | ||
70 | + } | ||
71 | + } | ||
72 | + | ||
73 | +</script> |
frontend/pages/vuetifyT.vue
0 → 100644
1 | +<template> | ||
2 | + <div> | ||
3 | + <PaddingMarginGrid/> | ||
4 | + </div> | ||
5 | +</template> | ||
6 | + | ||
7 | +<script> | ||
8 | + import Navbar from "../components/Navbar"; | ||
9 | + import PaddingMarginGrid from "../components/PaddingMarginGrid"; | ||
10 | + | ||
11 | + export default { | ||
12 | + name: "vuetifyT", | ||
13 | + components: {Navbar, PaddingMarginGrid} | ||
14 | + } | ||
15 | +</script> | ||
16 | + | ||
17 | +<style scoped> | ||
18 | + | ||
19 | +</style> |
frontend/plugins/README.md
0 → 100644
1 | +# PLUGINS | ||
2 | + | ||
3 | +**This directory is not required, you can delete it if you don't want to use it.** | ||
4 | + | ||
5 | +This directory contains Javascript plugins that you want to run before mounting the root Vue.js application. | ||
6 | + | ||
7 | +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins). |
frontend/static/README.md
0 → 100644
1 | +# STATIC | ||
2 | + | ||
3 | +**This directory is not required, you can delete it if you don't want to use it.** | ||
4 | + | ||
5 | +This directory contains your static files. | ||
6 | +Each file inside this directory is mapped to `/`. | ||
7 | +Thus you'd want to delete this README.md before deploying to production. | ||
8 | + | ||
9 | +Example: `/static/robots.txt` is mapped as `/robots.txt`. | ||
10 | + | ||
11 | +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static). |
frontend/static/favicon.ico
0 → 100644
No preview for this file type
frontend/static/v.png
0 → 100644
5.54 KB
frontend/static/vuetify-logo.svg
0 → 100644
1 | +<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 87.5 100"><defs><style>.cls-1{fill:#1697f6;}.cls-2{fill:#7bc6ff;}.cls-3{fill:#1867c0;}.cls-4{fill:#aeddff;}</style></defs><title>Artboard 46</title><polyline class="cls-1" points="43.75 0 23.31 0 43.75 48.32"/><polygon class="cls-2" points="43.75 62.5 43.75 100 0 14.58 22.92 14.58 43.75 62.5"/><polyline class="cls-3" points="43.75 0 64.19 0 43.75 48.32"/><polygon class="cls-4" points="64.58 14.58 87.5 14.58 43.75 100 43.75 62.5 64.58 14.58"/></svg> |
frontend/store/README.md
0 → 100644
1 | +# STORE | ||
2 | + | ||
3 | +**This directory is not required, you can delete it if you don't want to use it.** | ||
4 | + | ||
5 | +This directory contains your Vuex Store files. | ||
6 | +Vuex Store option is implemented in the Nuxt.js framework. | ||
7 | + | ||
8 | +Creating a file in this directory automatically activates the option in the framework. | ||
9 | + | ||
10 | +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store). |
frontend/store/index.js
0 → 100644
1 | +import Cookie from 'js-cookie'; | ||
2 | + | ||
3 | +export const state = () => ({}); | ||
4 | +export const mutations = {}; | ||
5 | +export const actions = { | ||
6 | + //새로고침마다 호출되는 함수 | ||
7 | + async nuxtServerInit({dispatch}, {req}) { | ||
8 | + try { | ||
9 | + const cookie = req.headers.cookie.split('=')[1]; | ||
10 | + console.log(cookie); | ||
11 | + await dispatch('user/loadMe', {cookie}); | ||
12 | + // await dispatch('post/loadPosts', {reset: true}); | ||
13 | + // await dispatch('waitingRoom/loadChatMe'); | ||
14 | + } catch (e) { | ||
15 | + console.error(e); | ||
16 | + } | ||
17 | + } | ||
18 | +}; | ||
19 | + | ||
20 | + | ||
21 | +// 1) state : 데이터 정의 | ||
22 | +// users, groups, user,files, file | ||
23 | +// 2) mutation : state에 있는 데이터들을 수정하는 작업 | ||
24 | +// user => 이름이 바뀌면 state에 있는 user 정보를 가지고 와서 수정하는 곳 | ||
25 | +// 3) action: 서버에다가 데이터를 요청하는 작업 | ||
26 | +// 서버에서 user 정보를 받아서 mutation에 state에 있는 user 정보를 내가 받은 정보로 수정하라고 요청 | ||
27 | + | ||
28 | + | ||
29 | +// state에서 데이터를 정의할 때 username, password 이런식으로 작은 단위로는 정의를 잘 안해 | ||
30 | +// user정보로 묶음으로 정의하는 거든 | ||
31 | +// user: { 'username' : '정수연', 'password': 'wjdtndus'} | ||
32 | +// file: { 'filename': , 'createdAt', 'deletedAt', 'isFolder'} | ||
33 | +// user: null, '', 0, True, False | ||
34 | + |
frontend/store/user.js
0 → 100644
1 | +import Cookie from 'js-cookie'; | ||
2 | + | ||
3 | +export const state = () => ({ | ||
4 | + me: null, | ||
5 | +}); | ||
6 | + | ||
7 | +export const mutations = { | ||
8 | + loadMe(state, payload) { | ||
9 | + const {user} = payload; | ||
10 | + state.me = user; | ||
11 | + }, | ||
12 | + login(state, payload) { | ||
13 | + const {user} = payload; | ||
14 | + state.me = user; | ||
15 | + }, | ||
16 | + logout(state) { | ||
17 | + state.me = null; | ||
18 | + } | ||
19 | +}; | ||
20 | + | ||
21 | +export const actions = { | ||
22 | +//mutation{commit} 호출 | ||
23 | + loadMe({commit}, payload) { | ||
24 | + return new Promise(async (resolve, reject) => { | ||
25 | + try { | ||
26 | + const {cookie} = payload; | ||
27 | + this.$axios.defaults.headers.common['Authorization'] = `Token ${cookie}`; | ||
28 | + const res = await this.$axios.get('http://54.180.112.94:8080/api/auth/loadMe', { | ||
29 | + withCredentials: true | ||
30 | + }); | ||
31 | + commit('loadMe', {user: res.data}); | ||
32 | + return resolve(); | ||
33 | + } catch (e) { | ||
34 | + console.error(e); | ||
35 | + return reject(e); | ||
36 | + } | ||
37 | + }) | ||
38 | + }, | ||
39 | + | ||
40 | + /* signUp */ | ||
41 | + signUp({commit}, payload) { | ||
42 | + return new Promise(async (resolve, reject) => { | ||
43 | + try { | ||
44 | + const {email, username, password} = payload; | ||
45 | + const res = await this.$axios.post('http://54.180.112.94:8080/api/auth/signUp', { | ||
46 | + email, username, password | ||
47 | + }, { | ||
48 | + withCredentials: true | ||
49 | + }); | ||
50 | + const {user, token} = res.data; | ||
51 | + if (process.browser) { | ||
52 | + localStorage.setItem('accessToken', token); | ||
53 | + Cookie.set('accessToken', token); | ||
54 | + console.log(localStorage); | ||
55 | + } | ||
56 | + | ||
57 | + commit('login', {user}); | ||
58 | + return resolve(); | ||
59 | + | ||
60 | + } catch (e) { | ||
61 | + console.log(res.data); | ||
62 | + console.error(e); | ||
63 | + return reject(e); | ||
64 | + } | ||
65 | + }) | ||
66 | + }, | ||
67 | + | ||
68 | + /* login */ | ||
69 | + login({commit}, payload) { | ||
70 | + return new Promise(async (resolve, reject) => { | ||
71 | + try { | ||
72 | + console.log(payload) | ||
73 | + const {username, password} = payload; | ||
74 | + console.log('login 실행'); | ||
75 | + const res = await this.$axios.post('http://54.180.112.94:8080/api/auth/login', { | ||
76 | + username,password | ||
77 | + }, { | ||
78 | + withCredentials: true | ||
79 | + }); | ||
80 | + console.log(res); | ||
81 | + // # 접근 성공 시, 토큰 값이 반환된다. | ||
82 | + // 토큰을 헤더 정보에 포함시켜서 유저 정보를 요청 | ||
83 | + // 토큰을 로컬 스토리지에 저장 | ||
84 | + const {user, token} = res.data; | ||
85 | + // console.log(user, token); | ||
86 | + if (process.browser) { | ||
87 | + localStorage.setItem('accessToken', token); | ||
88 | + Cookie.set('accessToken', token); | ||
89 | + console.log(localStorage); | ||
90 | + } | ||
91 | +/* | ||
92 | + login({commit}, payload) { | ||
93 | + return new Promise(async (resolve, reject) => { | ||
94 | + try { | ||
95 | + const {username, password} = payload; | ||
96 | + console.log('login 실행'); | ||
97 | + const res = await this.$axios.post('ec2-54-180-112-94.ap-northeast-2.compute.amazonaws.com:8000/rest-a | ||
98 | +uth/google', { | ||
99 | + username, password | ||
100 | + }, { | ||
101 | + withCredentials: true | ||
102 | + }); | ||
103 | + | ||
104 | + console.log(res); | ||
105 | + // # 접근 성공 시, 토큰 값이 반환된다. | ||
106 | + // 토큰을 헤더 정보에 포함시켜서 유저 정보를 요청 | ||
107 | + // 토큰을 로컬 스토리지에 저장 | ||
108 | + const {user, token} = res.data; | ||
109 | + console.log(user, token); | ||
110 | + if (process.browser) { | ||
111 | + localStorage.setItem('accessToken', token); | ||
112 | + Cookie.set('accessToken', token); | ||
113 | + console.log(localStorage); | ||
114 | + } | ||
115 | +*/ | ||
116 | + | ||
117 | + | ||
118 | + commit('login', {user}); | ||
119 | + return resolve(); | ||
120 | + | ||
121 | + } catch (e) { | ||
122 | + console.error(e); | ||
123 | + return reject(e); | ||
124 | + } | ||
125 | + }); | ||
126 | + }, | ||
127 | + | ||
128 | + /* logout */ | ||
129 | + logout({commit}) { | ||
130 | + return new Promise(async (resolve, reject) => { | ||
131 | + try { | ||
132 | + // await this.$axios.get('http://127.0.0.1:8000/user/logout', { | ||
133 | + // withCredentials: true | ||
134 | + // }); | ||
135 | + if (process.browser) { | ||
136 | + localStorage.removeItem('accessToken'); | ||
137 | + Cookie.remove('accessToken'); | ||
138 | + } | ||
139 | + commit('logout'); | ||
140 | + return resolve(); | ||
141 | + | ||
142 | + } catch (e) { | ||
143 | + console.error(e); | ||
144 | + return reject(e); | ||
145 | + } | ||
146 | + }) | ||
147 | + }, | ||
148 | + | ||
149 | + | ||
150 | + socialLogin({commit}){ | ||
151 | + console.log('zz') | ||
152 | + console.log(this) | ||
153 | + return new Promise(async (resolve, reject) => { | ||
154 | + try{ | ||
155 | + const res = await this.$axios.post('http://ec2-54-180-112-94.ap-northeast-2.compute.amazonaws.com:8080/accounts/google/login/callback/main/',{ withCredentials: true }); | ||
156 | + console.log(res); | ||
157 | + | ||
158 | + }catch(e){ | ||
159 | + console.error(e); | ||
160 | + return reject(e); | ||
161 | + } | ||
162 | + }) | ||
163 | + } | ||
164 | + | ||
165 | + | ||
166 | +}; | ||
167 | + | ||
168 | + | ||
169 | +// mutations -> 함수 인자로 (state, payload) => state / payload -> actions | ||
170 | +// actions -> 함수 인자로 ({commit}, payload) => commit mutations / payload | ||
171 | + | ||
172 | +// new Promise -> 비동기, 동기 | ||
173 | + | ||
174 | +// 동기 | ||
175 | +// 동시에 처리된다는 말은 실행되고 결과가 무조건 동시에 나와야한다는 뜻이야 | ||
176 | +// print(1) print(2) print(3) => 1, 2, 3 | ||
177 | + | ||
178 | +// 비동기 | ||
179 | +// print(1) print(2, => 1초) print(3) => 1,3,2 (default) | ||
180 | + | ||
181 | +// Promise 비동기식 작업을 처리한다 | ||
182 | +// 로그인 요청 => 서버로 로그인 데이터를 보내주세요 => 서버로부터 온 데이터를 mutation을 통해 state.me의 값을 수정해주세요 | ||
183 | +// 그 작업을 비동기적으로 실행되는 작업을 처리하겠다 => Promise ( 순차적으로 실행되게 하는거야 ) => | ||
184 | +// Username, password => user 정보가 오지 않았어 (성공, 실패) => user: null 인 상태에서 state.me 수정해버리는 거야 => user 정보가 오는거야 | ||
185 | +// 그래서 뭐를 하냐 new Promise => 내부에 로직같은걸로 무조건 기다려야 하는 작업에 기다리라는 속성을 줘! 서버에서 user 정보를 받아와야 하는 작업에 user정보가 올때까지 기다려 라는 로직같은 걸 줘! | ||
186 | + | ||
187 | +// return new Promise( async(resolve, reject)=> { | ||
188 | +// try{ | ||
189 | +// | ||
190 | +// }catch (e) { | ||
191 | +// | ||
192 | +// } | ||
193 | +// }) | ||
194 | + |
-
Please register or login to post a comment