回答編集履歴

3 誤字修正

nico25

nico25 score 828

2020/01/15 02:06  投稿

## ポイント
`session`, `g`, `flash` の 3 つ import して使います。
* セッションには `session` を使います。
* `g` と session は区別するといいと思います。
* 認証の成功と失敗のメッセージは `flash` を使うといいと思います。
* 認証の成功と失敗のメッセージは `flash` を使うといいと思います。
まだ書きかけですが...
* [Flask の session と g](https://python.ms/context/)
## ログアウト
ログアウトは実装していないので、ログアウトを実装すると練習になるかなと思います。
sessison から 'user_name' を消すとログアウトします。
```python
del session['user_name']
```
## コード
```python
# app.py
from flask import Flask, request, render_template, g, session, redirect, url_for, flash
app = Flask(__name__)
app.config['SECRET_KEY'] = "your_secret_string"
class User:
   def __init__(self, name, password):
       self.name = name
       self.password = password
       # 本来、平文でのパスワードは原則 NG です。
       # パスワード、ソルトなどで検索してください。
users = [
   User('aaa', 'aaa123'),
   User('bbb', 'bbb123'),
]
@app.before_request
def load_logged_in_user():
   user_name = session.get('user_name')
   if user_name is None:
       g.user = None
       return
   users_ = [user for user in users if user.name == user_name]
   if len(users_) != 1:
       g.user = None
       return
   g.user = users_[0]
def login_required(view):
   def wrapped_view(**kwargs):
       if g.user is None:
           flash('login required')
           return redirect(url_for('index'))
       return view(**kwargs)
   return wrapped_view
@app.route('/', methods=["GET", "POST"])
def index():
   if request.method == 'POST':
       user_name = request.form['user_name']
       password = request.form['password']
       users_ = [user for user in users if user.name == user_name and user.password == password]
       if users_:
           user = users_[0]
           session['user_name'] = user.name
           flash('You were successfully logged in')
           return redirect('profile')
       else:
           flash('login failure')
   return render_template("index.html")
@app.route("/profile", methods=["GET"])
@login_required
def profile():
   return render_template('profile.html')
if __name__ == "__main__":
   app.run(debug=True)
```
```html
<!-- index.html -->
{% with messages = get_flashed_messages() %}
 {% if messages %}
   <ul>
   {% for message in messages %}
     <li>{{ message }}</li>
   {% endfor %}
   </ul>
 {% endif %}
{% endwith %}
<form action="/" method="post">
 <p>user name: <input type="text" name="user_name" size="40" /></p>
 <p>password: <input type="password" name="password" size="40" /></p>
 <p>
   <input type="submit" value="submit" />
   <input type="reset" value="reset" />
 </p>
</form>
```
```html
<!-- profile.html -->
{% with messages = get_flashed_messages() %}
 {% if messages %}
   <ul>
   {% for message in messages %}
     <li>{{ message }}</li>
   {% endfor %}
   </ul>
 {% endif %}
{% endwith %}
```
2 誤字修正

nico25

nico25 score 828

2020/01/15 01:58  投稿

セッションには `session` を使います。
認証の成功と失敗のメッセージは `flash` をを使うといいと思います。
`session` と `g` は区別するといいと思います。
## ポイント
`session`, `g`, `flash` の 3 つ import して使います。
* セッションには `session` を使います。
* `g` と session は区別するといいと思います。
* 認証の成功と失敗のメッセージは `flash` をを使うといいと思います。
まだ書きかけですが...
* [Flask の session と g](https://python.ms/context/)
 
 
## ログアウト  
 
ログアウトは実装していないので、ログアウトを実装すると練習になるかなと思います。  
sessison から 'user_name' を消すとログアウトします。  
 
 
```python  
del session['user_name']  
```  
 
## コード  
```python
# app.py
from flask import Flask, request, render_template, g, session, redirect, url_for, flash
app = Flask(__name__)
app.config['SECRET_KEY'] = "your_secret_string"
class User:
   def __init__(self, name, password):
       self.name = name
       self.password = password
       # 本来、平文でのパスワードは原則 NG です。
       # パスワード、ソルトなどで検索してください。
users = [
   User('aaa', 'aaa123'),
   User('bbb', 'bbb123'),
]
@app.before_request
def load_logged_in_user():
   user_name = session.get('user_name')
   if user_name is None:
       g.user = None
       return
   users_ = [user for user in users if user.name == user_name]
   if len(users_) != 1:
       g.user = None
       return
   g.user = users_[0]
def login_required(view):
   def wrapped_view(**kwargs):
       if g.user is None:
           flash('login required')
           return redirect(url_for('index'))
       return view(**kwargs)
   return wrapped_view
@app.route('/', methods=["GET", "POST"])
def index():
   if request.method == 'POST':
       user_name = request.form['user_name']
       password = request.form['password']
       users_ = [user for user in users if user.name == user_name and user.password == password]
       if users_:
           user = users_[0]
           session['user_name'] = user.name
           flash('You were successfully logged in')
           return redirect('profile')
       else:
           flash('login failure')
   return render_template("index.html")
@app.route("/profile", methods=["GET"])
@login_required
def profile():
   return render_template('profile.html')
if __name__ == "__main__":
   app.run(debug=True)
```
```html
<!-- index.html -->
{% with messages = get_flashed_messages() %}
 {% if messages %}
   <ul>
   {% for message in messages %}
     <li>{{ message }}</li>
   {% endfor %}
   </ul>
 {% endif %}
{% endwith %}
<form action="/" method="post">
 <p>user name: <input type="text" name="user_name" size="40" /></p>
 <p>password: <input type="password" name="password" size="40" /></p>
 <p>
   <input type="submit" value="submit" />
   <input type="reset" value="reset" />
 </p>
</form>
```
```html
<!-- profile.html -->
{% with messages = get_flashed_messages() %}
 {% if messages %}
   <ul>
   {% for message in messages %}
     <li>{{ message }}</li>
   {% endfor %}
   </ul>
 {% endif %}
{% endwith %}
```
1 誤字修正

nico25

nico25 score 828

2020/01/15 01:44  投稿

セッションには `sessino` を使います。
セッションには `session` を使います。
認証の成功と失敗のメッセージは `flash` をを使うといいと思います。
`session` と `g` は区別するといいと思います。
* [Flask の session と g](https://python.ms/context/)
```python
# app.py
from flask import Flask, request, render_template, g, session, redirect, url_for, flash
app = Flask(__name__)
app.config['SECRET_KEY'] = "your_secret_string"
class User:
   def __init__(self, name, password):
       self.name = name
       self.password = password
       # 本来、平文でのパスワードは原則 NG です。
       # パスワード、ソルトなどで検索してください。
users = [
   User('aaa', 'aaa123'),
   User('bbb', 'bbb123'),
]
@app.before_request
def load_logged_in_user():
   user_name = session.get('user_name')
   if user_name is None:
       g.user = None
       return
   users_ = [user for user in users if user.name == user_name]
   if len(users_) != 1:
       g.user = None
       return
   g.user = users_[0]
def login_required(view):
   def wrapped_view(**kwargs):
       if g.user is None:
           flash('login required')
           return redirect(url_for('index'))
       return view(**kwargs)
   return wrapped_view
@app.route('/', methods=["GET", "POST"])
def index():
   if request.method == 'POST':
       user_name = request.form['user_name']
       password = request.form['password']
       users_ = [user for user in users if user.name == user_name and user.password == password]
       if users_:
           user = users_[0]
           session['user_name'] = user.name
           flash('You were successfully logged in')
           return redirect('profile')
       else:
           flash('login failure')
   return render_template("index.html")
@app.route("/profile", methods=["GET"])
@login_required
def profile():
   return render_template('profile.html')
if __name__ == "__main__":
   app.run(debug=True)
```
```html
<!-- index.html -->
{% with messages = get_flashed_messages() %}
 {% if messages %}
   <ul>
   {% for message in messages %}
     <li>{{ message }}</li>
   {% endfor %}
   </ul>
 {% endif %}
{% endwith %}
<form action="/" method="post">
 <p>user name: <input type="text" name="user_name" size="40" /></p>
 <p>password: <input type="password" name="password" size="40" /></p>
 <p>
   <input type="submit" value="submit" />
   <input type="reset" value="reset" />
 </p>
</form>
```
```html
<!-- profile.html -->
{% with messages = get_flashed_messages() %}
 {% if messages %}
   <ul>
   {% for message in messages %}
     <li>{{ message }}</li>
   {% endfor %}
   </ul>
 {% endif %}
{% endwith %}
```

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る