【DRF×Next】环境配置 – 至Google登录
首先
这次我们会使用DjangoRestFramework来实现后端,并且使用Next(TypeScript)作为前端,使用react-oauth作为第三方库来快速构建Web应用开发的基础。
环境
Ubuntu 20.04
总结构成
PROJ #作成するプロジェクト
│── back # Django REST framework(以下DRF)のAPI
│ ├── api # モデル、ビュー、APIのルーティングなど
│ ├── env # venv
│ ├── manage.py # DRFのサーバ起動やマイグレーション
│ ├── project # DRFの設定もろもろの中核
│ └── requirements.txt # 必要なPythonパッケージ
│── front # フロントエンド
└── client # Reactアプリケーション
数据库 jī)
如果使用SQLite,则忽略这一点。
DRF默认使用SQLite数据库。
(sudo apt update && apt upgrade)
(sudo apt update && apt upgrade)
请使用以下命令在终端中安装MySQL服务器:sudo apt install mysql-server。
设置root用户的密码
运行mysql_secure_installation命令
用中文将以下内容释义,只需要一个选项:
mysql -uroot -p
使用MySQL创建数据库,命名为任意的数据库名。
mysql > 退出
后端
请将以下内容用中文表达,并简化为一个选项:
使用Django REST框架(DRF)。
请将其视为与Django不同的东西。
请安装Python 3的Django模块。
安装必要的库。
用Python创建一个名为env的虚拟环境。
「env」没有限制。
激活源中的env/bin。
Django
djangorestframework
django-cors-headers
drf_social_oauth2
mysqlclient
※django-cors-headers是必需的,以允许来自不同端口的前端通信。
在中文中只需要一个选项进行重新表述:通过以下命令安装所有依赖包:`pip install -r requirements.txt`
如果有后续添加的库,将更新requirements.txt文件。
把pip freeze的结果输出到requirements.txt文件中。
创建一个Django项目。
请用母语汉语重新表达以下内容,仅需提供一种选择:
django-admin startproject project .
运行django-admin命令,创建名为”project”的项目 。
(项目名称为“项目”,可以自行命名)
创建一个应用程序
用中文原生地转述以下内容,只需要一种选项:
使用python3 [manage.py](http://manage.py/) startapp api命令。
(应用程序名称”API”是可选的)
调整设置文件
-
- 使用するライブラリと上で作成したapp名を登録
-
- db設定(dbエンジン, host, user, password)
- 言語、地域設定(日本・アジア・東京)
以下是代码片段的示例。
INSTALLED_APPS = [
'app',
'rest_framework',
'corsheaders',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware'
]
DATABASES = {
#デフォのSQLite設定はコメントアウトまたは削除
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 上で作成した任意のDB名,
'USER': 'root',
'PASSWORD': 上で設定したrootのパスワード,
}
}
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
]
创建管理员
请使用Python3运行manage.py文件创建超级用户。
在上面设置的数据库的auth_user表中创建。
※以下是在API直屬範圍內的操作。
定义模型
要在 models.py 中描述要创建的表格。
接下来,我将举一个例子。
from django.db import models
# Create your models here.
class User(models.Model):
email = models.EmailField(
verbose_name='Eメールアドレス',
max_length=255,
unique=True,
)
name = models.CharField(max_length=100)
family_name = models.CharField(max_length=100)
given_name = models.CharField(max_length=100)
picture = models.CharField(max_length=200)
active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name # 管理画面での一覧に表示する値。なくてもいいし別の値でもいい。
⑦我的迁移
使用Python3运行”manage.py makemigrations api”命令。
执行以下命令:python3 manage.py migrate。
如果您要在应用程序的模型中定义新的表格,请再次执行上述两个命令。
使管理界面可执行操作
添加想要管理的模型。
以下是一个添加User表的示例。
from django.contrib import admin
from .models import User
# ここに使用するモデルを設定してください
admin.site.register(User)
根据第九个请求创建CRUD操作的视图。
序列化器.py
首先,设置序列化器。
Django没有的功能。由于DRF独特,您需要创建一个新文件。
序列化程序可以在数据库记录和模型之间进行复杂数据的桥梁传输。
以下是一个例子。
from .models import User
from rest_framework import serializers
# from django.db.models import fields
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','email','name','family_name','given_name','picture','active','created_at','updated_at')
views.py的解释
views.py的含义
views.py的定义
解释了views.py
以下是使用基于类的视图的示例(也可以使用基于函数的定义)。
根据DRF公式,以下有以下的好处。
可以为特定的HTTP方法(如GET、POST等)分配独立的方法,而不是使用条件分支来区分代码集合。
可以使用诸如Mixin(多重继承)等面向对象的技术,将代码分解为可重复使用的组件。
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.generics import get_object_or_404
from .models import User
from .serializer import UserSerializer
class UserListCreateAPIView(APIView): # 全データ取得とデータ追加についてのクラス
def get(self, request): # 全データ取得
articles = User.objects.filter(active=True)
serializer = UserSerializer(articles, many=True)
return Response(serializer.data)
def post(self, request): # データ追加
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class UserDetailAPIView(APIView): # idをもとに個別データ取得
err_msg = {
"error": {
"code": 404,
"message": "Article not found",
}}
def get_object(self, pk):
user = get_object_or_404(User, pk=pk)
return user
def get(self, request, pk):
user = self.get_object(pk)
serializer = UserSerializer(user)
return Response(serializer.data)
def put(self, request, pk):
user = self.get_object(pk)
serializer = UserSerializer(user, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk):
user = self.get_object(pk)
user.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
10个API的端点和管理界面的路由
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include('app.urls')) # APIのバージョンを表記するのがREST界隈での慣習らしいです。
]
from django.urls import path
from .views import (
UserListCreateAPIView,
UserDetailAPIView
)
urlpatterns = [
path("user/", UserListCreateAPIView.as_view(), name="article-list"),
path("user/<int:pk>", UserDetailAPIView.as_view(), name="article-detail"),
]
开启
运行命令 “python3 manage.py runserver”。
开始服务器运行
本地主机:8000/管理员
在管理界面上直接修改表格。
本地主机:8000/api/v1/用户
本地主机:8000/api/v1/user/(用户id)
请尝试进行HTTP通信。
请尝试使用”GET”、”POST”、”PUT”和”DELETE”方法来操作一下。
之后可以通过React侧的axios HTTP通信库发送HTTP请求,你会很容易地感受到响应的返回。
前端
以下是在本地中文环境下可以进行的方式,以允许使用Google帐号进行身份验证并通过POST方法向DRF添加用户:
1. 创建一个Django项目并设置好虚拟环境。
2. 通过pip安装所需的软件包。包括Django、Django REST框架以及任何其他与Google身份验证相关的软件包。
3. 在Google开发者控制台上创建一个新项目,并启用Google身份验证API。
4. 在Google开发者控制台上创建一个OAuth 2.0客户端ID,并获取对应的客户端ID和客户端密钥。
5. 在Django项目的设置中,配置Google API凭据,将客户端ID和客户端密钥添加到设置文件中。
6. 创建一个Django视图来处理Google帐号身份验证,并在成功验证后获取用户的访问令牌。
7. 创建一个Django视图来处理DRF中的POST请求,使用访问令牌检查用户的身份验证,并在通过验证后添加用户到数据库中。
8. 运行Django开发服务器,并确保可以通过路由调用相关的视图功能。
注意:要进行Google身份验证,可能需要在Google开发者控制台设置回调URL并获取相关授权。详细的步骤请参考相关文档和指南。
笔者的Node环境
查看节点版本
版本18.12.1.
npm版本号是多少。
8月19日的第2个
npx -v 的中文本地化解释:查询 npx 版本
8月19日第2代
创建应用程序
用中文原生方式重新表达:
使用 npx create-react-app client 命令创建React应用程序。
或者
创建一个Next.js应用程序,文件夹名为”client”。
如果使用Next.js,可以与位于pages文件夹下的目录结构相连动,这样路由就变得很方便。
但是这次我们暂时不使用 Next.js 的后端功能。
如果create-app不顺利,尝试清除缓存并删除.npm。
使用原生的中文释义以下内容,只需提供一种解释:
强制清除 npm 缓存
删除 ~/.npm 目录
只需要一种选择,请将以下内容用中文进行释义:
– 安装所需的npm软件包以实现googleOAuth认证并向DRF发送请求。
使用 npm 安裝最新版本的 @react-oauth/google、axios 和 jwt-decode。
react-oauth
ReactでGoogleOAuth認証するためのライブラリ。
react-google-loginというライブラリもあるが、非推奨。
axios
javascriptでのhttp通信を簡単に実装できるライブラリ。
Promissベース(処理が完了するまで次の処理に移行しない。)
jwt-decode
react-oauthで認証成功した際のレスポンスにcredentialというキーがある。
JWTという符号化やデジタル署名の仕組みを規定した標準規格であるためデコードする必要がある。
デコードするとユーザ名、メアド、プロフィール写真のURLなどを取得可能。
获得OAuth客户端ID
如果你看了下面这篇文章,就可以很容易地实现。
使用React和Django进行Google OAuth登录【前篇】从Google Developer Console获取客户端ID和客户端密钥。
画面的实现
以下是使用Next.js + TypeScript实现的示例。
import { GoogleOAuthProvider } from '@react-oauth/google';
import { GoogleLogin } from '@react-oauth/google';
import axios from "axios";
import jwt_decode from 'jwt-decode'
const googleClientId: string = クライアントID;
const baseURL: string = "localhost:8000/api/v1";
const handleGoogleLogin = (response: any) => {
console.log("response",response)
var decoded: any = jwt_decode(response.credential)
console.log("decoded",decoded)
const body = {
"email": decoded.email,
"name": decoded.name,
"family_name": decoded.family_name,
"given_name": decoded.given_name,
"picture": decoded.picture
}
axios.post(`${baseURL}/user/`, body)
.then((res) => {
console.log("Success Google login", res)
window.location.href = "/"
})
.catch((err) => {
console.log("Error Google login", err);
});
};
export default function Login() {
return (
<div>
<GoogleOAuthProvider clientId={googleClientId}>
<GoogleLogin
onSuccess={(response) => handleGoogleLogin(response)}
onError={() => {
console.log('Login Failed');
}}
/>
</GoogleOAuthProvider>
</div>
)
}
启动&GoogleOAuth认证
运行 npm 的 dev 命令
请进行认证并确认数据库。
只要 api_user 表中添加了用户就可以了。
请参考