回答編集履歴

2

修正

2016/06/13 06:54

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -1,4 +1,4 @@
1
- ロジック部分とHTML部分ごちゃまぜになっていますこういう書き方をすると,`ob_start`が最初に実行されていない限り,ヘッダが正しく送信されなくなってしまいます.**最初にロジックを全て固めて,HTMLはやるべきことを全てやってから出し始める**,というのを徹底してください.
1
+ header.phpの`include`はロジックが全て終わってからにしてください.`ob_start`が最初に実行されていない限り,認証などに絡むHTTPヘッダが正しく送信されなくなってしまいます.**最初にロジックを全て固めて,HTMLはやるべきことを全てやってから出し始める**,というのを徹底してください.
2
2
 
3
3
 
4
4
 
@@ -6,4 +6,202 @@
6
6
 
7
7
 
8
8
 
9
+ 【修正案】
10
+
11
+
12
+
13
+ ```php
14
+
15
+ <?php
16
+
17
+
18
+
19
+ // エラーをデバッグのために全表示する
20
+
21
+ ini_set('display_errors', true);
22
+
23
+ error_reporting(E_ALL);
24
+
25
+
26
+
27
+ // 必要な関数群を読み込む
28
+
29
+ require_once __DIR__ . '/functions.php';
30
+
31
+
32
+
33
+ // 未ログインセッションを要求し,ログイン済みの場合は / に遷移する
34
+
35
+ require_unlogined_session();
36
+
37
+
38
+
39
+ // ユーザから受け取ったユーザ名,パスワード,CSRFトークン
40
+
41
+ $tel_mail = filter_input(INPUT_POST, 'tel_mail');
42
+
43
+ $password = filter_input(INPUT_POST, 'password');
44
+
45
+ $token = filter_input(INPUT_POST, 'token');
46
+
47
+
48
+
49
+ // POSTメソッドのときのみ実行
50
+
51
+ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
52
+
53
+
54
+
55
+ try {
56
+
57
+
58
+
59
+ // データベースから情報取得
60
+
61
+ // (提示されていないdb_con.phpの書き方が怪しいので敢えて書き直します)
62
+
63
+ $pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '', [
64
+
65
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // SQL実行時のエラーもPDOExceptionに変換する
66
+
67
+ ]);
68
+
69
+ $stmt = $pdo->prepare('SELECT * FROM user WHERE tel = :tel_mail OR mail = :tel_mail LIMIT 1');
70
+
71
+ $stmt->execute(compact('tel_mail')); // compactは ['tel_mail' => $tel_mail] の省略形
72
+
73
+ $user = $stmt->fetch(PDO::FETCH_ASSOC);
74
+
75
+
76
+
77
+ } catch (PDOException $e) {
78
+
79
+
80
+
81
+ // PDOでエラーが発生したとき
82
+
83
+ // テキストで「500 Internal Server Error」
84
+
85
+ header('Content-Type: text/plain; charset=UTF-8');
86
+
87
+ http_response_code(500);
88
+
89
+ exit('データベース障害: ' . $e->getMessage());
90
+
91
+
92
+
93
+ }
94
+
95
+
96
+
97
+ // CSRFバリデーションおよびパスワードハッシュの検証
98
+
99
+ // (ユーザ名が存在しないときだけ極端に速くなるのも防ぐ)
100
+
101
+ if (
102
+
103
+ validate_token($token) &&
104
+
105
+ password_verify($password, $user ? $user['password'] : '$2y$10$abcdefghijklmnopqrstuv')
106
+
107
+ ) {
108
+
109
+ // 認証が成功したとき
110
+
111
+ // セッションIDの追跡を防ぐ
112
+
113
+ session_regenerate_id(true);
114
+
115
+ $_SESSION['user_id'] = $user['user_id']; // (ログインの証拠はこれの存在を見ればOK)
116
+
117
+ // ログイン完了後に / に遷移
118
+
119
+ header('Location: /');
120
+
121
+ exit;
122
+
123
+ }
124
+
125
+
126
+
127
+ // 認証が失敗したとき
128
+
129
+ // 「403 Forbidden」
130
+
131
+ http_response_code(403);
132
+
133
+
134
+
135
+ }
136
+
137
+
138
+
139
+ // HTMLとして表示
140
+
141
+ header('Content-Type: text/html; charset=UTF-8');
142
+
143
+
144
+
145
+ ?>
146
+
147
+ <?php include('header.php'); ?>
148
+
149
+ <main id="regist">
150
+
151
+ <div class="container">
152
+
153
+ <section class="container">
154
+
155
+ <form class="form-horizontal" action="" method="post">
156
+
9
- (あとでここに追記します)
157
+ <fieldset>
158
+
159
+ <div class="clearfix"></div><br>
160
+
161
+ <div class="input-group input-group-lg">
162
+
163
+ <span class="input-group-addon"><i class="glyphicon glyphicon-user red"></i></span>
164
+
165
+ <input type="text" class="form-control" placeholder="電話番号またはメールアドレス" name="tel_mail" value="<?=h($tel_mail)?>">
166
+
167
+ </div>
168
+
169
+ <div class="clearfix"></div><br>
170
+
171
+ <div class="input-group input-group-lg">
172
+
173
+ <span class="input-group-addon"><i class="glyphicon glyphicon-lock red"></i></span>
174
+
175
+ <input type="password" class="form-control" placeholder="パスワード" name="password">
176
+
177
+ </div>
178
+
179
+ <div class="clearfix"></div>
180
+
181
+ <div class="col-sm-12">
182
+
183
+ <button type="submit" class="btn btn-default center-block">ログイン</button>
184
+
185
+ </div>
186
+
187
+ </fieldset>
188
+
189
+ <input type="hidden" name="token" value="<?=h(generate_token())?>">
190
+
191
+ </form>
192
+
193
+ <?php if (http_response_code() === 403): ?>
194
+
195
+ <p style="color: red;">ユーザ名またはパスワードが違います</p>
196
+
197
+ <?php endif; ?>
198
+
199
+ </section>
200
+
201
+ </div>
202
+
203
+ </main>
204
+
205
+ <?php include('footer.php'); ?>
206
+
207
+ ```

1

a

2016/06/13 06:54

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -1,8 +1,4 @@
1
1
  ロジック部分とHTML部分がごちゃまぜになっています.こういう書き方をすると,`ob_start`が最初に実行されていない限り,ヘッダが正しく送信されなくなってしまいます.**最初にロジックを全て固めて,HTMLはやるべきことを全てやってから出し始める**,というのを徹底してください.
2
-
3
-
4
-
5
- エラーは発生しているけど非表示になっている,に1票.
6
2
 
7
3
 
8
4