php mysql でsql injectionに対応したhashログイン処理を実装した例

# php mysql でsql injectionに対応したログイン処理を実装した例
phpとmysqlでセッションログイン処理を実装するときにとかそういうのを作るのが面倒だったので、exampleを残します。。

## 依存パッケージのinstall
```
composer require josegonzalez/dotenv     
```

## ログイン処理をするとき
```php
// sign up
$userInfo = $login->signup("username","xxx@example.com", "12345678");

//login
$userInfo = $login->login("xxx@example.com", "12345678");

//check
$userInfo = $login->check();
if(!$userInfo)
    //ログインできていな

//logout
$userInfo = $login->logout();
```

## ログイン処理のクラス
ログイン処理のクラスファイルを作成

```php:login.php
<?php

/*
 * phpとmysqlでセッションログイン処理を実装するときにとかそういうのを作るのが面倒だったので、exampleを残します。。
 * made : ryosuke ando <ryo@ando.link>
 *
 */


require_once __DIR__ . "/vendor/autoload.php";

use  josegonzalez\Dotenv\Loader as Dotenv;


class login
{
    private $dbh;

    public function __construct()
    {
        $appDir = __DIR__;
        Dotenv::load([
            'filepath' => $appDir . '/.env',
            'toEnv' => true
        ]);

        $mysqlUser = $_ENV['MYSQL_USER'];
        $mysqlPass = $_ENV['MYSQL_PASS'];
        $mysqlHost = $_ENV['MYSQL_HOST'];
        $mysqlDbName = $_ENV['MYSQL_DBNAME'];

        $dsn = sprintf("mysql:host=%s;dbname=%s;charset=UTF8", $mysqlHost, $mysqlDbName);
        try {
            $this->dbh = new PDO($dsn, $mysqlUser, $mysqlPass);
            $this->dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            echo "error: " . $e->getMessage() . "\n";
            exit(1);
        }
    }

    public function login($email, $password)
    {
        /*
         * ログイン失敗なら、エラーを返します
         * 成功なら、
         */
        $sql = "SELECT * FROM users WHERE mail = ?";

        $sth = $this->dbh->prepare($sql);

        $sth->bindParam(1, $email, PDO::PARAM_STR);
        $sth->execute();

        $userInfo = $sth->fetch(PDO::FETCH_ASSOC);

        if (!$userInfo)
            //ユーザー名が間違えている
            return null;

        if (!password_verify($password, $userInfo['password']))
            //パスワードが間違えている
            return null;

        session_start();
        $_SESSION["user_info"] = $userInfo;
        return $userInfo;
    }

    public function check()
    {
        /*
         * ログインされていれば、ログイン情報を連想配列で返します。
         * ログインに失敗しているならば、nullを返します。
         */

        session_start();
        //ログインされているかチェックし、ログイン
        if (!isset($_SESSION["user_info"]))
            return null;

        return $_SESSION["user_info"];
    }

    public function logout()
    {
        session_start();
        $_SESSION["user_info"] = null;
    }

    public function signup($name, $email, $password)
    {
        $sql = "INSERT INTO users (`username`,`mail`,`password`) VALUES (?,?,?)";

        $sth = $this->dbh->prepare($sql);
//        echo password_hash($password, PASSWORD_BCRYPT);

        $sth->bindParam(1, $name, PDO::PARAM_STR);
        $sth->bindParam(2, $email, PDO::PARAM_STR);
        $sth->bindParam(3, password_hash($password, PASSWORD_BCRYPT), PDO::PARAM_STR);
        $sth->execute();

        $userInfo = $sth->fetch(PDO::FETCH_ASSOC);
        session_start();
        $_SESSION["user_info"] = $userInfo;
        return $userInfo;
    }
}

```
[https://qiita.com/singlestroke/items/b38f9f9f9b62f2522539](https://qiita.com/singlestroke/items/b38f9f9f9b62f2522539)
[https://qiita.com/KosukeQiita/items/b56b3004413c999b9858](https://qiita.com/KosukeQiita/items/b56b3004413c999b9858)
[https://qiita.com/zaburo/items/1dd2337c5f9281f7cc3a](https://qiita.com/zaburo/items/1dd2337c5f9281f7cc3a)
[https://ja.stackoverflow.com/questions/5053/php-%E3%81%A7%E3%81%AE-sql-%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%AF%BE%E7%AD%96%E3%81%AF%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E8%A1%8C%E3%81%84%E3%81%BE%E3%81%99%E3%81%8B](https://ja.stackoverflow.com/questions/5053/php-%E3%81%A7%E3%81%AE-sql-%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%AF%BE%E7%AD%96%E3%81%AF%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E8%A1%8C%E3%81%84%E3%81%BE%E3%81%99%E3%81%8B)
[https://www.php.net/manual/ja/pdostatement.fetch.php](https://www.php.net/manual/ja/pdostatement.fetch.php)
[https://qiita.com/rana_kualu/items/3ef57485be1103362f56](https://qiita.com/rana_kualu/items/3ef57485be1103362f56)