Django REST Frameworkに再挑戦 その24 Django Rest Framework JWT & Curl Tests
概要
Django REST Frameworkに再挑戦 その24 Django Rest Framework JWT & Curl Tests
参考サイト
www.codingforentrepreneurs.com
Django Rest Framework JWT & Curl Tests
- Django Rest Framework JWTの公式ページをチェックしてみる。認証関連のpackage。
JSON Web Token Authentication support for Django REST framework.
らしい。
$ pip install djangorestframework-jwt
する。settings.pyのREST FRAMEWORKの設定に以下のように追記する。
REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ), # 'DEFAULT_PARSER_CLASSES': ( # 'rest_framework.parsers.JSONParser', # ), 'DEFAULT_AUTHENTICATION_CLASSES':( 'rest_framework.authentication.SessionAuthentication', 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', #'rest_framework.authentication.BasicAuthentication', #こちらはオススメしないとのこと。 ), 'DEFAULT_PERMISSION_CLASSES':( 'rest_framework.permissions.IsAuthenticated', ), }
rest_framework.authentication.SessionAuthentication
はコメントアウトしてもOK。urls.pyに、JWT用のurlを設定する。
from rest_framework_jwt.views import obtain_jwt_token #... urlpatterns = patterns( '', # ... url(r'^api/auth/token/', obtain_jwt_token), # urlの箇所だけ微妙に変えてある。 )
- テスト用のshell スクリプトも用意されているので、settings.pyなどにメモっておく。
''' You can easily test if the endpoint is working by doing the following in your terminal, if you had a user created with the username admin and password password123. $ curl -X POST -d "username=user名&password=********" http://127.0.0.1:8000/api/auth/token/ '''
シェルで、
$ curl -X POST -d "username=user名&password=********" http://127.0.0.1:8000/api/auth/token/
を打って、tokenが表示されたらOK。テストとして、シェルに表示されたtokenをメモっておき、次のテストに使う。
先ずは、curl http://127.0.0.1:8000/api/comments/ としておき、認証が必要なサイトに行ってみる。。。
{"detail":"Authentication credentials were not provided."}
と表示されたので、取得できなかったことがわかる。次に、
$ curl -H "Authorization: JWT <your_token>" http://127.0.0.1:8000/api/comments/
でアクセスしてみる。。。取得できた〜〜!さらに、commentの投稿も試してみる。ヘッダー2つで、パスとコンテンツ部分を渡す。
curl -X POST -H "Authorization: JWT ***********************************.*********************************.-1XWtO99XlA75fahKjLdSLxfa3f6kbDo1qpcCmUTopE" -H "Content-Type: application/json" -d '{"content":"this is content"}' 'http://127.0.0.1:8000/api/comments/create/?slug=my-title&type=post'
- さらに、parent_idでスレッドにもコメントできるか確認する。
curl -X POST -H "Authorization: JWT ***********************************.*********************************.-1XWtO99XlA75fahKjLdSLxfa3f6kbDo1qpcCmUTopE" -H "Content-Type: application/json" -d '{"content":"this is content"}' 'http://127.0.0.1:8000/api/comments/create/?slug=my-title&type=post&parent_id'
- これは便利やな〜!
Django REST Frameworkに再挑戦 その23 Django Rest Framework Settings
概要
Django REST Frameworkに再挑戦 その23 Django Rest Framework Settings
参考サイト
www.codingforentrepreneurs.com
Django Rest Framework Settings
- Django Rest Frame WorkのSettingsについて見てみる。
Settings - Django REST framework
- settings.pyに、追記する。
REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', ), 'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', ) }
- Classesの箇所は、タプル形式になっているので、追記できる。 'rest_framework.renderers.BrowsableAPIRenderer'もデフォルトで設定されている。手動で設定する場合は、以下のような形で挿入する。
REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ), 'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', ), }
- DEFAULT_AUTHENTICATION_CLASSESの設定をする。
'DEFAULT_AUTHENTICATION_CLASSES':( 'rest_framework.authentication.SessionAuthentication', # 'rest_framework.authentication.BasicAuthentication', #こちらはオススメしないとのこと。 ),
- DEFAULT_PERMISSION_CLASSESの設定をする。
'DEFAULT_PERMISSION_CLASSES':( 'rest_framework.permissions.AllowAny', )
- 例えば、
IsAuthenticated
をデフォルトにしたい場合は、以下のように設定する。
'DEFAULT_PERMISSION_CLASSES':( 'rest_framework.permissions.IsAuthenticated', ),
- その場合、デフォルトのpermission_classesが、IsAuthenticatedになるため、各APIViewのpermission_classesを修正していく。
Django REST Frameworkに再挑戦 その22 User Detail Serailizer
概要
Django REST Frameworkに再挑戦 その22 User Detail Serailizer
参考サイト
www.codingforentrepreneurs.com
User Detail Serailizer
- user detailのAPIViewを作成したい。そしてそれをcommentsのdetailViewに表示させたい。まず、accounts/api/serializers.pyにコードを追記する。
class UserDetailSerializer(ModelSerializer): class Meta: model = User fields = [ 'username', 'email', 'first_name', 'last_name', ]
- 次に、comments/api/serializers.pyにUserDetailSerializerをimportする。
from accounts.api.serializers import UserDetailSerializer ... class CommentChildSerializer(ModelSerializer): user = UserDetailSerializer() ... class CommentDetailSerializer(ModelSerializer): user = UserDetailSerializer() ...
- このままでは、comment api viewからuserの編集ができてしまうので、read_only=Trueを追記しておく。
user = UserDetailSerializer(read_only=True)
- post/api/serializers.pyのuserの箇所も同様に、
user = UserDetailSerializer(read_only=True)
に置き換えておく。
Django REST Frameworkに再挑戦 その21 UserLogin API Validation
概要
Django REST Frameworkに再挑戦 その21 UserLogin API Validation
参考サイト
www.codingforentrepreneurs.com
UserLogin API Validation
- accounts/api/serializers.pyのUserLoginSerializer に、validationをつける。
class UserLoginSerializer(ModelSerializer): ... def validate(self, data): user_obj = None email = data.get("email", None) username = data.get("email", None) password = data["password"] if not email or not username: raise ValidationError("A username or email is required to login.") user = User.objects.filter( Q(email=email) | Q(username=username) ).distinct() if user.exists() and user.count() == 1: user_obj = user.first() else: raise ValidationError("ユーザー、emailが存在しません。") if user_obj: if not user_obj.check_password(password): raise ValidationError("パスワードが正しくありません。") data["token"] = "SOME RANDOM TOKEN" return data
- ただ、このvalidationでは、emailが登録されてない人たちがリストとして表示されてしまうので、以下の一文を差し込む。これは、nullと、"(空欄)"のリストを除くという意味だと思う。
user = user.exclude(email__isnull=True).exclude(email__iexact='')
- これでログイン実装完了か〜、この辺は、ライブラリの利用が必要なきがするな。
Django REST Frameworkに再挑戦 その20 Base APIView for User Login
概要
Django REST Frameworkに再挑戦 その20 Base APIView for User Login
参考サイト
www.codingforentrepreneurs.com
Base APIView for User Login
- UserLoginSerializerというclassを新たに作成する。
class UserLoginSerializer(ModelSerializer): token = CharField(allow_blank=True, read_only=True) username = CharField() email = EmailField(label='Email Address') class Meta: model = User fields = [ 'username', 'email', 'password', 'token', ] extra_kwargs = {"password": {"write_only": True} } def validate(self, data): # email = data['email'] # user_qs = User.objects.filter(email=email) # if user_qs.exists(): # raise ValidationError("すでにこちらのアドレスは登録されています。") return data
- accounts/api/views.pyにLoginViewを作成する。
class UserLoginAPIView(APIView): permission_classes = [AllowAny] serializer_class = UserLoginSerializer def post(self, request, *args, **kwargs): data = request.data # request.POST serializer = UserLoginSerializer(data=data) if serializer.is_valid(raise_exception=True): new_data = serializer.data return Response(new_data, status=HttP_200_OK) # ここのresponseは、rest_frameworkのAPIなので注意。 return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)
Django REST Frameworkに再挑戦 その19 Serializer Validation
概要
Django REST Frameworkに再挑戦 その19 Serializer Validation
参考サイト
www.codingforentrepreneurs.com
Serializer Validation
- serializers.pyにコードを追記する。
... class UserCreateSerializer(ModelSerializer): email = serializers.EmailField(label='Email Address') #emailフィールドのserializerによる上書き email2 = serializers.EmailField(label='Confirm Email') #confirm用のフィールド。 class Meta: model = User fields = [ 'username', 'email', 'email2', 'password', ] extra_kwargs = {"password": {"write_only": True} } def validate_email2(self, value):#validate_フィールド名で、validationをセットできるぽい。 data = self.get_initial() email1 = data.get("email") email2 = value if email1 != email2: raise ValidationError("Emailが一致していません。") return value ....
- 次は、重複したemailの登録がないかをvalidateする。
def validate(self, data): email = data['email'] user_qs = User.objects.filter(email=email) if user_qs.exists(): raise ValidationError("すでにこちらのアドレスは登録されています。") return data
- これをvalidate_emailに含める。
def validate_email(self, value):#validate_フィールド名で、validationをセットできるぽい。 data = self.get_initial() email1 = data.get("email2") email2 = value if email1 != email2: raise ValidationError("Emailが一致していません。") user_qs = User.objects.filter(email=email2) if user_qs.exists(): raise ValidationError("すでにこちらのアドレスは登録されています。") return value
Django REST Frameworkに再挑戦 その19 ModelSerializer Create Method
概要
Django REST Frameworkに再挑戦 その19 ModelSerializer Create Method
参考サイト
www.codingforentrepreneurs.com
ModelSerializer Create Method
- account/api/serializers.py にコードを追記する。
class UserCreateSerializer(ModelSerializer): class Meta: model = User fields = [ 'username', 'password', 'email', ] extra_kwargs = {"password": {"write_only": True} } def create(self, validated_data): return validated_data
- これだけでは、createメソッドを上書きしているだけなので、ここに処理を加えていく。
class UserCreateSerializer(ModelSerializer): class Meta: model = User fields = [ 'username', 'email', 'password', ] extra_kwargs = {"password": {"write_only": True} } def create(self, validated_data): username = validated_data['username'] email = validated_data['email'] password = validated_data['password'] user_obj = User( username = username, email = email, ) user_obj.set_password(password) user_obj.save() return validated_data
- これで、/api/users/register/にアクセスして、登録してみる。。。。さらに登録したuserでログインしてみる。。。できた〜!