LoginSignup
75
59

More than 1 year has passed since last update.

イタズラ投稿者のIPアドレスを、簡単に取得する方法(Laravel)

Last updated at Posted at 2021-01-31

##はじめに

私は未経験からプログラミングを学習して、Laravel等の技術を使用した
自作アプリをポートフォリオとして一般公開していました。

すると幸いにも、多くの方に実際にアプリを利用してもらうことができたものの、
やはりイタズラ投稿や連続投稿等、迷惑な投稿もされるようになりました。

→そんな体験の一部をまとめた記事:
ポートフォリオのアプリを公開したらイタズラされまくった話
(1,000LGTM突破ありがとうございます🙇‍♂️)

そこで、次の対策にも繋げるために、アプリに**「投稿者のIPアドレスを取得する機能」**を追加することにしました。
調べてみると、Laravelで非常に簡単に実現できることがわかったので、今回はその方法をご紹介いたします。

##前提条件

私は、以下の環境等で実現しました。

  • Laravel 6.18.36
  • 既に投稿機能が実装されている

##実際に、イタズラ投稿者のIPアドレスを取得してみた

まず初めに、デモンストレーションです。
私が公開しているアプリへの、イタズラ投稿者のIPアドレスを取得してみます。
では、どんなイタズラ投稿があるというと・・

スクリーンショット 2021-01-22 9.44.53.png

はい!下ネタ全開のイタズラ投稿ですね。笑
このような投稿が、日々ちょくちょく投稿されていました。^^;

ということで、IPアドレスを取得する処理を実装済みなので、
早速IPアドレスが取れたか確認してみます。

※ゲストユーザーというのは、パスワード等を入力しなくても、誰でも簡単にログイン可能なユーザーのことです。

###DBの中身を確認してみた

ということで、DBを覗いてみました。

スクリーンショット 2021-01-22 9.46.38のコピー.png

おぉ。。ip_addressカラムにしっかりと、下ネタ投稿者のIPアドレスが取得できていました。
流石にIPアドレスをこのまま載せるのは避けますが、赤色
伏せてる部分が、同一IPアドレスでした。
一方青色で伏せている部分は、それ以外の複数のIPアドレスです。

###三日間の投稿の、IPアドレスを調べてみた

2020年1月21日〜23日の投稿を確認してみました。

スクリーンショット 2021-01-23 17.04.21.png

  • 赤色で伏せてる部分が、全て同一IPアドレスでした。
     1月22日から23日にかけて、下ネタを投稿したり、「おはようございます!」と連続投稿していたことがわかります。

  • 青色で伏せている部分は、それ以外の複数のIPアドレスです。

  • ip_addressカラムの中身が「NULL」となっているものは、IPアドレスを取得する処理が未実装だった頃の投稿です。IPアドレスが取得できていません。

こうして見てみると、下ネタ投稿ユーザーが
二日間に渡って投稿してきていることがわかります。
同一人物だったんか・・・というのがわかるとちょっと面白いですよね。

それでは、いよいよIPアドレス取得機能の実装方法についてご紹介していきます。

##IPアドレスの取得方法

これが、とても簡単です。
Requestクラスの、ip()メソッドを利用するだけです。
ユーザーがアプリ上で投稿を行った際に、Controller側でユーザーのIPアドレスを
$request->ip() といった形で扱うことができます。

例えば、投稿機能に関する処理をまとめたControllerである
ArticleController.phpに、
登録処理を定義したstore()メソッドがあるとします。
内容としては、ユーザーが投稿したメッセージを、そのままDBに保存するだけのシンプルな処理です。

ArticleController.php
public function store(ArticleRequest $request, Article $article)
{
    // 投稿をDBに保存
    $user = $request->user();
    $article = $user
                ->articles()
                ->create($request->validated()); // バリデーション済みの値だけ保存
    return redirect()->route('articles.index');
}

※ちなみに、上記のコードでは、$request->validated()で、バリデーション済みの値のみを取得しています。
こちらの方が、$request->all()で値を取得するより安全です。

それでは、storeメソッドの処理の一番最初に、試しにdd( )メソッド$request->ip()を取ってみましょう。
この状態で、アプリから自分で適当な投稿をしてみると、ちゃんと自分のIPアドレスが取得できていることが確認できると思います。

ArticleController.php
public function store(ArticleRequest $request, Article $article)
{
    dd($request->ip());  // 投稿者のIPアドレスが取得できているか確認

    // 投稿をDBに保存
    $user = $request->user();
    $article = $user
                ->articles()
                ->create($request->validated()); // バリデーション済みの値だけ保存
    return redirect()->route('articles.index');
}

たったこれだけでIPアドレスを取得できてしまうので、Laravelって本当に便利ですね。。

なお、本記事でご紹介する実装の主な手順としては、以下のようになっています。
(あまり難しくありません)

  1. DBのarticlesテーブルに、「ip_address」カラムを追加し、IPアドレスを保存できるようにする。
  2. 上記store()メソッドで、IPアドレスをDBに保存するようコードを編集
  3. fillableにコードを一行追加

※投稿に関する情報を保存するDBのテーブルを、articlesテーブルと定義する場合

##IPアドレス取得機能の実装方法

###DBのテーブルに、IPアドレス用のカラムを追加

本記事では、以下の前提で実装を進めていきます。

  • ユーザー投稿に関する情報を保存するテーブルを、articlesテーブルとする
  • IPアドレスを保存するカラムを、ip_addressカラムとする

まずカラム追加のマイグレーションファイルを作成します。
ターミナルから以下のコマンドを実行してください。

$ php artisan make:migration add_ip_address_to_articles_table --table=articles

新しいマイグレーションファイルが作成されるので、そちらを以下のように編集してください。

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddIpAddressToArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        // ここから追記 ーーーーーーーーーーーーーーーーー
        Schema::table('articles', function (Blueprint $table) {
            $table->ipAddress('ip_address')->nullable();
        });
        // 追記ここまで ーーーーーーーーーーーーーーーーー
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        // ここから追記 ーーーーーーーーーーーーーーーーー
        Schema::table('articles', function (Blueprint $table) {
            $table->dropColumn('ip_address');
        // 追記ここまで ーーーーーーーーーーーーーーーーー
        });
    }
}

新しく追加するip_addressカラムの
カラムタイプにはipAddressを指定しており、
またIPアドレスが取得できなかった際にエラーで落ちないようにnullableもかけています。

参考:Laravel 6.x データベース:マイグレーション

マイグレーションファイルの編集が完了したら、マイグレーションを実行します。

$ php artisan migrate

これでDBにip_addressカラムが追加されました。

###Controller側に、IPアドレスを保存する処理を追加

先ほど例に出しました、ArtcleController.phpの一行に追記します。

ArticleController.php
public function store(ArticleRequest $request, Article $article)
{
    // 投稿をDBに保存
    $user = $request->user();
    $article = $user
                ->articles()
                ->create($request->validated() + ['ip_address' => $request->ip()]); // 取得したIPアドレスを保存するよう修正
    return redirect()->route('articles.index');
}

ここでは、DBへの保存処理を行うcreate()メソッドの引数を編集しています。
バリデーション済みの値である、
$request->validated()という連想配列に、更に1つ + 演算子で連想配列の要素を追加しています。
追加された連想配列が、['ip_address' => $request->ip()]です。
'ip_address'というキーに、バリューとして取得したIPアドレス$request->ip()を対応させています。
(今回、取得したIPアドレスはバリデーションにはかけていません。)

###fillableを追加
最後に、モデルのArticle.php$fillableに、一行追記します。
(以下のモデルは一例なので、みなさんの環境によって異なると思います。)

Article.php
<?php

namespace App\Models;

use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Article extends Model
{
    protected $fillable = [
        'body',
        'user_id',
        'ip_address', // `ip_address`を追加
    ];

// 〜〜〜〜〜〜〜〜〜 略 〜〜〜〜〜〜〜〜〜

}

以上で、IPアドレスを取得する機能の実装は完了です!
お疲れ様でした!
これで、アプリ上でユーザー投稿があった時に、そのユーザーのIPアドレスをDBに保存できるようになりました。

##最後に
今回は、Laravelで簡単に投稿者のIPアドレスを取得する方法をご紹介しました。
IPアドレスを取得した先に繋げる迷惑投稿対策としては、

  • 特定のIPアドレスにアクセス制限をかける
  • 犯罪性の高い悪質な投稿に関しては、プロバイダーに問い合わせる等する

といったものが考えられると思います。

なお、IPアドレス取得機能を実装したアプリを公開する際には、プライバシーポリシー等を作成しておくことが望ましいです。
こちらのサイトで、コピペOKなプライバシーポリシーのテンプレートが公開されているので、ご自身のアプリ用に少し修正したものを作成しておきましょう!
【コピペOK】ブログのプライバシーポリシー書き方&設置方法を公開

75
59
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
75
59