Let’s EncryptとCertbotでSSL取得

AsameshiCode

今日の課題 今日は、Let’s EncryptとCertbotを使ってTLS/SSL Certificationを無料で取得します。 今回はウェブサーバーはnginxで行いますが、apacheでも同じことができます。 ちなみに、nginxではデフォルトファイルとは別のサーバーブロックを作成します。ドメイン毎にサーバーブロックをそれぞれ作成することでドメインごとの設定ができます。 準備するもの ・Ubuntuサーバー(20.04) ・root 権限(もしくはsudo権限のユーザー) ・ドメイン(なんとか.com) ・すでにnginxがインストールされていることを前提です。 ・/etc/nginx/sites-available/example.comでアプリがデプロイされていることが前提です。 ・SSHでサーバーに接続できる状態。 ・コマンドラインを使ったことがない人には理解をすることが難しい内容です。 Certbotのインストール では、SSHでサーバーに接続します。私はMobaXtermという無料ツールを2年くらい使っています。詳しいMobaXtermの使い方はこちらの記事を読んでください。 では、Certbotを入れます。 毎回、何を入れているのか公式サイトから確認する癖をつけましょう。 https://certbot.eff.org/ で、下記のコマンドからインストールします。 これでCertBotの準備ができましたが、nginxの方で設定が必要なのでこれからやっていきます。 Nginxの設定 CertBotに自動でSSLを取得するために、正しいサーバーブロックを探すように指示してあげなければいけません。 この記事で説明しているように下記のファイルを先に設定しましょう。 このファイルの中に下記のラインがあることを確認してください。 Nginxのテストをします。 エラーが出た場合はコンフィグを修正してnginxをリロードしましょう。 HTTPSをファイアウォールで許可する Ubuntuサーバーで使われているファイヤーウォールの設定は下記のコマンドで確認できます。 Inactive の場合はsudo ufw enableでアクティブにします。この時にSSHのポートを許可しておきましょう。 では、nginxのポートを許可します。 ここまでできたらCertBotを使ってSSLを取得します。 SSL Certificateを取得 では下記のコマンドでSSLを取得しましょう。 ここで、色々聞かれるので答えていきます。 root@localhost:/etc/nginx/sites-available# sudo certbot –nginx -d ドメイン.com -d www.ドメイン.com Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: … Read more

DjangoでAPIをつくろう

知っておくべきこと

・Djangoの基本は説明しませんので別の動画/記事で先に理解しておくこと

・Pythonの基本

・APIの意味

今回使用するもの

・Windows10(OSはあまり関係ありません)

・Python3

・pip

・Django REST framework

Django REST Frameworkってなに?

Django自体はバックエンドのフレームワークの中でもスピーディに開発でき、セキュリティも設定されてるいてくる優れモノです。

他にはPHPのLaravelとか、nodeJSのExpressJSとかが近いもので存在します。

詳しくはDjangoの公式ドキュメンテーションを見てください。

https://www.djangoproject.com/

しかし!実際の開発の現場では、Djangoだけの仕事っていうのはあまりありません。DjangoにAPIを組み込んでマルチプラットフォーム(Web、モバイルアプリ、exeファイル)からデータにアクセスさせるというやり方の方が良いです。

これでDjangoの良さを活かしつつ、ユーザー側にはreact、vue、Anguler等のJSフレームワークでフルスタックにする方がスケールもしやすく、デバッグも楽になります。

では、前置きはこれくらいにして早速Django RESTFramework(DRF)を触っていきましょう。

DRFが提供するAPIの種類

APIでは、JSONファイルのデータを公開したり、アプリのデータを発信、受け取る際に使います。例えば天気の情報をAPIで受け取り、自分のサイトに表示するとかですね。

serializerを理解する

Djangoは通常PostgreSQLなどのデータベースと接続されています。デフォルトでは、SQLiteというポータブルのDB(データベース)がついてきますが、セキュリティのこともあり、デプロイする際には使いません。

DRFのSerializerはこのデータベースのデータをシリアル化することによってDjangoアプリからデータをAPIとして公開する役目を持ちます。

views.pyを理解する

ではこのシリアル化されたデータをDjangoのViews.pyというファイルの中でどのように扱うか指示をしてあげます。ここでフィルターをしたり、順番を変えたりもできます。

urls.pyを理解する

最後にどのURLでクライアント(ユーザー側)がアクセスできるかを指示します。

セットアップ

Pythonが入っていることを確認してください。

python –version

python3 —version

仮想環境を使ってホストターミナル(つまりは私のWIndowsPC)から独立した環境を作ります。必要ない人は飛ばしてください。(OSによってコマンドが異なります。)

環境を作りたいファイルパスで下記のコマンド

ENVは私がつけた名前なのでなんでもいいです。

pip install virtualenv

Virtualenv ENV

ENV\Scripts\activate.bat

Djangoのインストール

pip install django
pip list

プロジェクトの作成

Djangoがインストールできたら下記のコマンドでdjangoのプロジェクトを作成します。

django-admin startproject djangoapi

#djangoapiの部分は自分で分かりやすいものにしてください。

で、新しいプロジェクト名のディレクトリができました。

次にDjangoのRESTフレームワークをインストールします。

pip install djangorestframework

pip list

アプリの追加

今できたプロジェクトファイルとは別にアプリケーションごとのディレクトリを作成します。

まずはmasnage.pyのある場所に移動します。

cd djangoapi

python manage.py startapp apiapp

settings.pyを設定

ではテキストエディタでメインのプロジェクトファイルのsettings.pyを開き、

INSTALLED_APPS にrest_frameworkを追加します。

あとさっき作ったapiappも登録します。

INSTALLED_APPS = [

    'django.contrib.admin',

    'django.contrib.auth',

    'django.contrib.contenttypes',

    'django.contrib.sessions',

    'django.contrib.messages',

    'django.contrib.staticfiles',

    'rest_framework',

    'apiapp',

]

プロジェクトのurls.pyを設定

これもdjangoの設定なので詳しくは説明しません。

apiappのurls.pyに転送します。

from django.contrib import admin
from django.urls import path, include


urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('apiapp.urls'))
]

アプリの方にurls.pyを作成しておく。

from django.urls import path

urlpatterns = [
]

アプリ側のviews.pyの設定

データベースに接続する前に簡単なテキストデータが出力できるか試します。

ここでapiの設定の仕方でファンクションベースとクラスベースの設定の仕方があります。

ファンクションベースは細かい設定がしやすいですが、行が長くなりがちで、クラスベースはコードの数が少ないと違いと考えておいて問題ないと思います。

from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.decorators import api_view



@api_view(['GET'])
def getData(request):
  person = {'name':'Shiro', 'age':31}
  return Response(person)

さっきのurls.pyにエンドポイントを作成

from django.urls import path
from .views import getData

urlpatterns = [
    path('api/', ('apiapp.urls')),
    path('', getData),
]

テストラン

python manage.py makemigrations

Python manage.py migrate

python manage.py runserver

http://127.0.0.1:8000/をブラウザで開く。

これでAPIのエンドポイントが設定できましたね。

では、実際のデータを参照するように設定します。l

メンバーアプリを作成する。

では、同じ要領でメンバーのデータを参照するAPIを作成していきます。

python manage.py startapp members

settings.pyにアプリを登録

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    # Installed app
    'apiapp',
    'members'
]

モデルの登録

モデルはデータベースの方のようなもので、Django側でデータベースで受け入れるデータの種類やデータの長さを規制しておくことができます。

では、models.pyで下記のように例としてモデルを登録します。

from django.db import models

class Members(models.Model):
  name = models.CharField(max_length=30)
  email = models.EmailField(max_length=60)
  phone = models.IntegerField()
  date = models.DateTimeField(auto_now_add=True)

  #auto_now_addはレコードの作成した日と時間のみ記録する

モデルをシリアル化する

では、このmembersモデルをAPIにするための作業を行います。

Membersディレクトリ内にserializers.pyを作成します。

from rest_framework import serializers
from .models import Members




class MembersSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=30)
    email = serializers.EmailField(max_length=60)
    phone = serializers.IntegerField()
    date = serializers.DateTimeField()



    class Meta:
        model = Members
        # fields = ['name', 'email', 'phone', 'date']
        fields = '__all__'

Viewsの登録

今回はクラスベースでAPIにしてみましょう。

クラスベースの中でもいくつか方法があります。

まずは基本となるAPIviewを使ったやり方を紹介しますが、Viewsetという.CRUDの全部がセットになったものもあります。(CRUDはクリエイト、リード、アップデート、デリートpの略)

from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView
from .models import Members
from .serializers import MembersSerializer




class MemberList(APIView):
    def get(self, request, format=None):
        members = Members.objects.all()
        serializer = MembersSerializer(members, many=True)
        return Response(serializer.data)




Urls.pyの設定

プロジェクト側のurls.pyをアプリ側に転送して、アプリ側のurls.pyでclassのMemberListのエンドポイントを作成します。

#djagoapi/urls.py

from django.contrib import admin
from django.urls import path, include



urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('apiapp.urls')),
    path('members/', include('members.urls')),
]

#members.urls.py

from django.urls import path
from .views import MemberList

urlpatterns = [
    path('', MemberList.as_view()),
]

DBをマイグレーション

では、実際にAPIができたかを確認する前に、models.pyのDBの枠組みを流し込みます。

python manage.py makemigrations

python manage.py migrate

python manage.py runserver

テストデータの作成

ではデータが空っぽなのでテスト用に入れていきます。

python manage.py createsuperuser

アドミンパネルにアクセスする前にDBモデルを登録して表示できるようにします。

#members/admin.py

from django.contrib import admin
from .models import Members
# Register your models here.
admin.site.register(Members)

ウェブサーバーを実行してURLからアドミンパネルにアクセスします。

http://127.0.0.1:8000/admin/

Djangoが勝手にmembersにsをつけたのでmodels.pyで変更します。

from django.db import models


class Members(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField(max_length=60)
    phone = models.IntegerField()
    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name_plural = 'Members'


    def __str__(self):
        return self.name

Pluralは複数形のことです。

あと、__str__の所で、どのように表示したいか教えてあげます。この場合はメンバーのnameのデータを返してあげるようにします。

では、データ登録してみましょう。

では、これでAPIのエンドポイントに行ってみるとAPIが出力されていることが分かりますね!

では、次回はこのDjango RESTFrameworkのAPIでPOSTリクエストやDELETEのリクエストを送ってユーザー側から記事の投稿や削除ができるようにします。

お楽しみに。