危機感を持った理系学生のプログラミング日記

AWSで作成したWebポートフォリオSSL化🦊

awsで作成したポートフォリオSSL化したのでその方法を備忘録として記事に残しときます。

 

ドメインの購入

ssl化するにはドメインを設定しなければならないのでまずはドメインを購入します。

awsでもドメインを購入できますが少し高いので今回は「お名前.COM」というサイトで購入しました。

先に誰かが使用しているドメインは取得できないので注意ですが、"-"などを入れると比較的取得しやすいです。(一部の記号は使用できない場合があります)

下記のサイトを参考にしました。

qiita.com

 

AWS側(Route53)の設定

AWSのRoute53を使ってDNSを設定していきます。

手順は下記のサイトを参考にしました。

qiita.com

 

Route53の使用料金は

  • 0.50USD ホストゾーンごと / 月、最初の 25 ホストゾーン
  • 0.10USD ホストゾーンごと / 月、追加ホストゾーン

となっています。

詳しくは下記の公式サイトより。

aws.amazon.com

 

「お名前.COM」で取得したドメインは使えるようになるまで少し時間がかかる事がありますが、

$dig xxxxxxx.com

ドメイン及びDNSの設定が上手くいっているか確認できます。

設定は上手くいっているのに繋がらないという場合は、サーバーの方の設定を見直してみましょう。私はnginxで運用していますが、ドメインをnginx及びAPサーバーのgunicornで設定していなかった為ずっとつながりませんでした。。。

http://xxxxx.xxx

で検索してみて繋がれば成功です。

 

Let's EncryptでSSL証明書取得

DNS設定が完了したのでいよいよSSL化です。

正直難しくて全ては理解できていません。

取得の方法は色々あるみたいでサーバーの環境によっても変わるみたいです。

今回私はnginxを利用しているのでnginx用の方法を書きたいと思います。

手順としては

  1. Let's Encryptから証明書を取得するためにサーバーの設定を変更する。
  2. Let's Encryptから証明書を取得してくる。
  3. SSL証明書を適用するためにサーバーの設定を変更する。
  4. Let's EncryptのSSL証明書の有効期限は90日間であるため、証明書を定期的に更新することが必要です。なのでcronにコマンドを登録して自動化します。

 

1の設定変更には様々な記事がありどれも同じようで違う手法を用いていたので、どれを参考にすれば良いか迷いましたが、私は下記の記事を参考にしました。

qiita.com

 

一応これで完了になります。

ただ色々と設定ファイルを書き加えてしまうので実行する場合は自己責任で。

また何かあれば記事にします。

では🦊

 

危機感を持った理系学生のプログラミング日記

こんばんわ🦊

絶賛就活中ですが、ポートフォリオdjangoで作成してAWSで本番公開したのでその手順を備忘録として書き残しとこうと思います。

今回は一般的なWebの構造であるWeb三層構造に基づいてアプリを作成しています。

WebサーバーをNginx、APサーバー(WSGIサーバー)はGunicorn、DBサーバーはAWSのRDSを用いています。

手順としては

  1. AWSでEC2インスタンスとRDSの立ち上げ
  2. EC2インスタンスDjangoアプリ作成とRDSとの接続
  3. 静的ファイルやメディアファイルをS3から配信するために、S3を立ち上げる
  4. nginxとguiconのインストールと設定

 

 

1. EC2インスタンスとRDSの立ち上げ

RDSの立ち上げについて主に書いていきます。

RDSを立ち上げるにはVPC内に異なるリージョンのサブネットを2つ以上作成しなくてはなりません。(セキュリティの関係?)

今回はMariaDBを使いましたが、慣れているDBを使うのが◯

デフォルトでは、立ち上げたDBの文字コードがバラバラなので設定からutf-8に変更する必要があります。

この記事がわかりやすいです。

qiita.com

 

2. DjangoとRDSの接続

作成したRDSとDjangoを接続していきます。

DjangoはデフォルトではSQlite3になっています。

SQlite3はWebアプリケーションとしても、単一インスタンスでアクセスが少なく、可用性も低くてよいWebアプリケーションでは十分に使えます。

が、SQlite3はあくまで開発用として使って、本番環境ではMySQLPostgreSQLを使うのが一般的ですので変更しときましょう。

下記のサイトが分かりやすいです。

qiita.com

 

3. 静的ファイルやメディアファイルをS3から配信する

Djangoは開発環境ではdebug=trueでも良いですが、本番環境ではdebug=falseにします。

debug=falseにした場合、Djangoからcssや画像などの静的ファイルやメディアファイルが配信されなくなるので、S3から配信するようにします。

手順としては、S3に配信したいファイルをデプロイしてS3とDjangoを接続します。

下記のサイトが分かりやすいです。

blog.narito.ninja

qiita.com

 

4. nginxとguiconのインストールと設定

WebサーバーであるNginxとAPサーバー(WSGIサーバー)のGunicornのインストールと設定をしていきます。

Nginxをインストール → Gunicornをインストール → NginxとGunicornの接続

という手順でやっていきます。

下記の記事が参考になります。

qiita.com

 

Gunicornの起動と停止は以下の手順でやります。

 

f:id:Catherinamu:20210206155831p:plain

 

下記の記事を参照しました。

cortyuming.hateblo.jp

 

あとは . . .

SSL認証などのセキュリティ周りの設定をすれば完成です。

リソースを監視する「CloudWatch」の導入もしたいと思っているのでそこらへんも記事にできたら良いなと思っています。

ではまた🦊

 

 

 

危機感を持った理系学生のプログラミング日記

こんばんわ🦊

まとめたいことができたので書いていきます。

XMLファイルをXMLパーサーに読み込んで解析し、viewに表示してみました。

yahooNewsのXMLファイルを解析して表示すれば、yahooNewsの記事がViewに表示できるようになります。様々なサイトがXMLファイルを公開しているので、tableViewや、SegementSlide等と組み合わせることで、色んなサイトが見栄えよくViewに表示できるようになります。

 

配列の復習

まず、モデルクラスに配列の要素にするためのクラスを作ります。

class NewsItem{

    

    var title:String!

    var url:String!

    var pubDate:String!

}

 

 

配列を扱いたいControllerクラスで、配列インスタンスを作成します。

この配列はNewsItem型の配列なので、1つの要素はtitle,url,pubDateのプロパティで構成されています。

この配列にappendした場合、[NewsItem,NewsItem,NewsItem,NewsItem] こんな感じになり、このNewsItem要素1つ1つに、title,url,pubDateのプロパティが入っています。

//NewsItem型の配列インスタンスを作成

    var newsItem = [NewsItem]()

 

 

XMLParser

 

didStartElement

XMLParserのデリゲートメソッドの1つです。

要素の開始タグがあったら実行されるメソッドです。

XMLParserのデリゲートメソッドでは最初に呼ばれます。

XMLパースの要素の名前がtitleなら、

currentElementName

nil(空)を入れ、newsItem配列に1つ要素(NewsItem型)を追加。

titleでないなら、

currentElementName

XMLパースの要素の名前を代入します。

// 解析中に要素の開始タグがあったときに実行されるメソッド

    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {

        

        currentElementName = nil

        if elementName == "item"{

            

            //配列の中にNewsItem型の要素を1つ追加

            //NewsItem型は、title,url,pubDateのプロパティで構成されている

            self.newsItem.append(NewsItem())

            

            print(elementName)

            print(self.newsItem)

            

            

        }else{

            

            currentElementName = elementName

            print(elementName)

        }

        

    }

 

 

foundCharacters

次に呼ばれるXMLParserのデリゲートメソッドです。

newsItem配列に要素が入っているなら、if文以下が実行されます。

ここで、newsItem配列の要素のプロパティに値を入れていきます。

 // 開始タグと終了タグでくくられたデータがあったときに実行されるメソッド

    func parser(_ parser: XMLParser, foundCharacters string: String) {

        

        print("要素:" + string)

        

        if self.newsItem.count > 0{

            

            let lastItem = self.newsItem[self.newsItem.count - 1]

            

            switch self.currentElementName {

            case "title":

                lastItem.title = string

                

            case "link":

                lastItem.url = string

                

            case "pubDate":

                lastItem.pubDate = string

                

            default:break

            

            }

        }

    }

 

 

didEndElement

3番目に呼ばれるXMLParserのデリゲートメソッドです。

XMLパースの要素の名前にnilを入れてリセットしています。

 // 解析中に要素の終了タグがあったときに実行されるメソッド

    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {

        

        print(elementName)

        

        self.currentElementName = nil

    }

 

 

これら3つのメソッドはXMLパースの要素の名前が変わる毎にグルグル呼ばれます。

実行結果はこんな感じになります。

item

[Swift5IntroApp1.NewsItem]

要素:

 

title

要素:本RSSのURLは変更になりました。新しいRSSのURLへ移行をお願いします。

title

要素:

 

link

要素:https://yahoo.jp/ibOrnq

link

要素:

 

item

要素:

 

item

[Swift5IntroApp1.NewsItem, Swift5IntroApp1.NewsItem]

要素:

 

 

TableViewで表示

 

XMLパーサーで取得したデータをTableViewを使って表示します。

その中でも特にややこしかった、didSelectRowAtに焦点を置きます。

TableViewのセルにXMLパーサーで取得したデータ(ニュースのタイトルとURL)が入っています。セルをタップすると、そのニュースタイトルとURLに基づいたデータをWebViewController(自作のcontroller)で表示します。

key値にニュースのURLの値を入れ、WebViewControllerの方でそれを受け取れるようにします。

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        

        //WebViewControllerにurl(キー)を渡して表示したい

        let webView = WebViewController()

        webView.modalTransitionStyle = .crossDissolve

        let news = newsItem[indexPath.row]

        UserDefaults.standard.set(news.url, forKey: "url")

    

        //webViewに画面遷移

        present(webView, animated: true, completion: nil)

        

    }

    

 

 

 

ざっくりとですが少しややこしかった所をまとめました。

ではまた🦊

危機感を持った理系学生のプログラミング日記

 

こんばんわ🦊

 

今は自作アプリを作ったり、基礎学習を進めています。

 

少し前に学習をした箇所を復習しました。その時は意味が分からず、頭がパンクしながらやっていたのですが今では何となく分かるようになってて成長を感じました🦊

それではまとめていきます。

 

リベンジFirebase🔥

Firebaseはとても便利というのは理解できているのですが、そもそもの扱い方についてよく分からなかった為、復習しました。

 

データ送信

f:id:Catherinamu:20201107203437p:plain

 

当たり前ですがimportでFirebaseのフレームワークを読み込んでいる前提になります。

 

 let chatDB = Database.database().reference().child("chats")

        

        let massageInfo = ["sender":Auth.auth().currentUser?.email,"message":messageText.text!]

ここでデータベースに保存するデータ形式とデータを登録する準備をしています。

 

 //chatDBに入れる

        chatDB.childByAutoId().setValue(massageInfo) { (error, result) in

            

            if error != nil{

                print(error)

            }else{

                print("送信完了")

                self.messageText.isEnabled = true

                self.sendBtn.isEnabled = true

                self.messageText.text = ""

                

            }

            

        }

        

ここでさっきのデータ形式を個別に識別できるようにchildByAutoIdというのを付与して実際に登録しています。

f:id:Catherinamu:20201107204141p:plain

こんな感じでchatsという箱の中に、IDと登録したい内容が登録されています。

このようなキーとデータを結びつけて表すデータ形式Jsonデータと言います🦊

Firebaseに値を登録する時はJsonデータの形式にして登録します。

 

データの受信

f:id:Catherinamu:20201107205353p:plain

 

.childAdded

はchildに新しいデータが追加されたらと言うのを表しています。

こっちもクロージャーになっていて、値がsnapShotに入ってきたら in 以下の処理を実行します。

 

 

書き方は慣れてないと難しく感じますが、今見てみるとそんなに複雑ではないので簡単に思えます。

jsonデータ形式で値を登録 → 登録した値を持ってくる  

この処理の流れが頭に入ってたらスッキリ理解できます。

ではまた🦊

危機感を持った理系学生のプログラミング日記

こんばんわ🦊

 

スロット好きの友達の為にオリジナルアプリを作成しました。

今回そのアプリが一旦完成したのでその紹介をしようと思います。

 

スロットアプリ

 

f:id:Catherinamu:20201019021624p:plain

 

1/72でBIGボーナスが、1/72でREGボーナスが当選します。

合算で1/36当選になります。

当選したらランプが点灯するという仕組みになります。

ジャグラーという有名なスロットをそのまま再現しました。

216分の1でプレミア演出が見れたりと、実装したい機能は実装することができました。

あとはBGMとかつけられたらいいなとか思っています。

 

このアプリを作った感想

このアプリ自体は基礎文法のみで作ったので難しくはありませんでしたが、アプリが完成した後にアプリ名を変更しようとプロジェクト名を変更したら大変なことになったので教訓としてここに書いていきます。

まず1つが、プロジェクト名を変えようとすると変更する場所が多くてあちこちでエラーが出て、複雑化すること。

2つ目が、日本語をプロジェクト名にするとエラーが出ること。

これらのエラーがややこしく、エラーを直しても真っ暗な画面から進まなくなったので注意です。

下記にこのアプリのコードを貼っときます。

github.com

 

今後

今後は基礎学習をしつつ、オリジナルアプリも作っていきたいと思っています。

では🦊

 

 

危機感を持った理系学生のプログラミング日記

こんにちは、狐であります🦊

外は絶賛台風です。ランニングができなくなるから迷惑極まりない。

さて、今回はFirebaseを使ってFacebookのログインを実装してみました。

Firebaseって聞いたことはあるけどなんぞや?から始まり、まだまだ分からない事だらけですが、凄い便利であることはわかりました。便利すぎて感動してます。

プログラミング以外にも色々使うための手順があり大変ですが、沢山やって慣れていきたいです。

今日はFirebase!!!!!

 

Firebaseって何?

ネイティブアプリやWebアプリなどをユーザーに提供するためには、バックエンド環境も構築する必要があります。しかし1から「API」サーバーを用意してアプリと連携を行ったり、ユーザー履歴を保持する仕組みを作ったりするには膨大な時間が掛かります。

Googleの提供しているFirebaseは、そんな悩みを解決してくれるツールです。Firebaseを使えば効率よくアプリを開発し、運用・管理ができるようになります。

Firebaseとは、Googleの提供する「MBaaS(Mobile Backend as a Service)」です。MBaaSとはモバイルアプリのバックエンド環境を提供するサービスの総称で、その中でも最も有名なのがFirebaseです。

モバイルアプリを開発する上で、ユーザーの目には見えないバックエンド環境をしっかり整えておくのも開発側の責任となります。しかしバックエンド環境構築に時間が掛かり、アプリリリースが遅れてしまっては元も子もありません。また自前でバックエンド環境を構築すると、メンテナンスなどの手間やコストも掛かります。

Firebaseでは、クラウドサーバーを活用してアプリを開発できます。これにより開発側は効率よくアプリを開発できるようになり、スピーディーにアプリをリリースできます。またメンテナンスなどの作業はGoogle側が代行してくれるので、開発側では手間やコストも掛けずに済みます。

つまり、自分でサーバー立てて、データベースを作って値を保存して、管理してみたいなのをやってくれるというわけです。

ユーザー認証を自分で実装するとなると、データベースになんやかんやしたり、いちいち管理したり凄い面倒臭かったのですが、Firebaseを使えばそういうのもやってくれます。

いやー、もっと早く知りたかった🦊

 

ただ、Firebaseを導入するには、導入したいアプリへの連携作業が必要になります。機能ごとにSDKなどが分かれており、指定された手順通りに実装しないとエラーが出る可能性もあるので公式サイトもよく確認しておきましょう。

これが意外と大変なのですが、自分で一からやる手間と比較したら屁でもないですね🦊

参考サイト

r-abo.com

 

Swiftで実装してみた

大事だなーと思ったコードを抜粋して書いていきます。

 

//ライブラリをインポート

import UIKit

import FBSDKCoreKit

import FBSDKLoginKit

import FacebookCore

import FacebookLogin

import Firebase

 

これは言わずもがなですね。ライブラリを使うのでimportは必須です。

 

view.addSubview(fbLoginButton)      //ビューを重ねて表示

このメソッドなんですが、viewに重ねてviewを表示させるといったメソッド。

これで、ログインボタンが表示されます。

 

 

func loginButton(_ loginButton: FBLoginButton, didCompleteWith result: LoginManagerLoginResult?, error: Error?) {

        

        //エラーがないのなら

        if (error == nil){

            

            //キャンセルボタンが押されたら

            if (result!.isCancelled == true){

                

                return

            }

        }

        

        //トークンを元にログインしてるらしい

        let credential = FacebookAuthProvider.credential(withAccessToken: AccessToken.current!.tokenString)

        

        //ここからfirebase

        Auth.auth().signIn(with: credential) { (result, error) in

            

            //エラーが出たら

            if let error = error{

                return

            }

            

            //resultの値を使ってなんやかんや

            self.displayName = result!.user.displayName!

            self.pictureURLString = result!.user.photoURL!.absoluteString

            

            //データ保存

            UserDefaults.standard.set(1, forKey: "loginOK")

            UserDefaults.standard.set(self.displayName, forKey: "displayName")

            UserDefaults.standard.set(self.pictureURLString, forKey: "pictureURLString")

            

            let nextVC = self.storyboard?.instantiateViewController(identifier: "next") as! NextViewController

            self.navigationController?.pushViewController(nextVC, animated: true)

            

        }

        

       

    }

    

 

このメソッドがメインになります。

流れとしては、 

ログインボタンが押される → Facebookトークンを使ってログイン → Firebaseと連携処理 → ログインユーザーの情報を取ってきて反映させる → ログイン状態や、ログインユーザーの情報を保存

って感じになります。

慣れないと難しいですね🦊

もし何かあれば追記します。では🦊

 

 

 

危機感を持った理系学生のプログラミング日記

こんにちは。外は雨です🦊

今日は珍しく夕方に書いてます。(16時)

 

先日から、APIJSON解析に手を出していました。少しまとめたのでそれを書いていきます。

 

APIって何??

APIとは「Application Programing Interface」の略になります。

言葉通りの意味で、APIとは、「アプリケーション、ソフトウェア」と「プラグラム」をつなぐもの、という意味になります。

APIとはソフトウェアやアプリケーションなどの一部を外部に向けて公開することにより、第三者が開発したソフトウェアと機能を共有できるようにしてくれるものです。USBは外部デバイスとパソコンを繋ぐインターフェースですが、APIはソフトウェア同士を繋げます。つまり、異なるソフトウェアやサービス間で認証機能を共有したり、チャット機能を共有したり、片方から数値データを取り込み、別のプログラムでそのデータを解析したりできるようになります。

とアプリを繋げることによって、機能性を拡張させ、さらに便利に使えるようにし、欲を言えば両方のアプリにとってウィン・ウィンの状態を生み出すのがAPIの狙いです。

 

APIで組み込むことができる信頼できるプログラムが世の中にすでに存在する場合、そのプログラムと連携することで、自分で1からプログラムを組む必要がなくなり、ソフトウェア開発の効率化がはかれます。プログラム開発側にとって、開発時間を短縮することができるのは大きなメリットです。時間短縮ができれば他の工程に時間を割くことができ、結果的にコスト削減が可能となります。

APIにもいくつか種類があり、多くの方が使うことになるのが、WEBの「API」つまりはWEBAPIと呼ばれるものです。名前が特に変わっていないので、覚えやすいですね。

WEBAPIはその名の通り、Web上に公開されていて、外部から呼び出して利用が可能なAPIです。

誰でも使用でき、かつ無料のものが多いので、多くのサービスがAPIを使っています。

WEBAPIにはamazonやyahoo、googleなどがあり、

AmazonAPIを利用すれば、自身のWebサイトで最新の売れ筋をすぐさまチェックすることができたりします。

また、前述の通り、FacebookTwitterなどのSNSが提供するAPIを利用すれば、SNS同士で記事を共有することができ、1つのSNSに記事投稿をしても、他のSNSにも同時投稿が可能になったりします。また、TogetterやNaverまとめなどのサービスもSNSと連携することで、サービスの利便性、そしてサービスの価値そのものを高めています。

Google Calendar APIは、Googleが提供しているGoogleカレンダーの各機能が使えるAPIです。お店の営業時間に使ったり、社内の会議の時間を共有したりすることで、無料で情報共有を不特定多数の人と可能にしてくれる優れものです。

APIすげーーーーーーー🦊

 

参考サイト

data.wingarc.com

 

JSONとは??

JSONとはJavaScript Object Notationの略で、XMLなどと同様のテキストベースのデータフォーマットです。

その名前の由来の通りJSONJavaScriptのオブジェクト表記構文のサブセットとなっており、XMLと比べると簡潔に構造化されたデータを記述することができるため、記述が容易で人間が理解しやすいデータフォーマットと言えます。

APIから貰うデータ形式jsonデータになります🦊

そのjsonデータを使いやすいようにすることをJSON解析と言います。

すごいざっくりですが。。。

 

 

実際にAPIを叩いてみた

今回はpixabayというフリー画像サイトのAPIを叩いてみました。

APIを叩くにはそのサイト毎にルールがありますのでそのルールに則って行います。

まず、APIキーというものを発行します。これは1ユーザーに1つ配られるユニークなものになっいます。

このAPIキーを使って、サイトのルールに従いデータを取得します。

下記が取得したjsonデータです。

f:id:Catherinamu:20201007163959p:plain

 

これをプログラミングに組み込んでアプリに反映させていきます。

 

//検索キーワードの値を元に画像を引っ張ってくる

    //pixabay.comからとってくる

    //値が返ってくるので、それをJSON解析する

    //imageView.imageに貼り付ける

    

    //メソッド作成

    func getImage(keyword:String){

        

        //APIkey

        let url = "https://pixabay.com/api/?key=18582240-c6c227f83fcc11ff577afaf3e&q=\(keyword)"

        

        //Alamofireを使ってhttpリクエストを投げる

        AF.request(url,method: .get,parameters: nil,encoding: JSONEncoding.default).responseJSON{(response) in

            

            switch response.result{

            

            

            case.success:

                //ここでJSON解析

                let json:JSON = JSON(response.data as Any)

                var imageString = json["hits"][self.count]["webformatURL"].string

                

                //imageStringが空だったなら0番目に戻す

                if (imageString == nil){

                    

                    imageString = json["hits"][0]["webformatURL"].string

                    self.odaiImageView.sd_setImage(with: URL(string: imageString!), completed: nil)

                }else{

                    

                    self.odaiImageView.sd_setImage(with: URL(string: imageString!), completed: nil)

                }

                

            case .failure(let error):

                print(error)

            }

            

        }

    }

    

 

流れとしては、Alamofireを使ってhttpリクエストを投げる→JSON解析→JSONデータの配列から欲しいデータを選んで変数に入れる→それを画像形式として表示

 

意外と簡単にできます🦊

JSON解析っていうくらいだから、沢山コードを書くんだろうなあと思っていたらまさかの一行😲

APIは凄い大事なのでもっともっと詰めます!!

では🦊