Flask Flask-JWT-Extended 사용해서 JWT 토큰 전송

bongf·2022년 3월 30일
3

정글

목록 보기
1/20

파이썬, Flask JWT

Flask_JWT에서 사용하는 라이브러리, Flask-JWT-Extended를 사용하면 좀 더 편리하게 사용할 수 있다고 하므로 이를 활용해보도록 하겠다.

  • 이 라이브러리는 Flask-JWT-Extended

Flask-JWT-Extended

  • 설치 pip install flask-jwt-extended

토큰값 생성 및 조회

https://flask-jwt-extended.readthedocs.io/en/stable/basic_usage/

  • app.config에 jwt 토큰을 만들 secretkey를 등록하고
    • app = Flask(__name__)
      app.config["JWT_SECRET_KEY"] = "super-secret"
      jwt = JWTManager(app)
  • 식별자를 설정하고 token을 생성한다. create_access_token(identity=username)
    • from flask_jwt_extended import create_access_token
      access_token = create_access_token(identity=username)
      ## return jsonify(access_token=access_token)
  • 로그인을 가정해서 임의로 id, password를 지정해 토큰 값을 발급해봤다.
from flask import Flask, jsonify

from flask_jwt_extended import JWTManager
from flask_jwt_extended import create_access_token

app = Flask(__name__)

app.config["JWT_SECRET_KEY"] = "munjibang"
jwt = JWTManager(app)

@app.route("/users/login", methods=['POST'])
def home():
    user_id = "id1"
    password = "password1"
    access_token = create_access_token(identity=user_id)
    print(access_token)
    return jsonify({"access_token":access_token})

if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)
  • 보이는 결과값

payload에 식별자 외에도 다른 정보를 넣어야 한다면

https://flask-jwt-extended.readthedocs.io/en/stable/add_custom_data_claims/ 이를 참고하자. https://github.com/vimalloc/flask-jwt-extended/issues/317

  • claim을 만들어서 넣어준다
        	@app.route("/login", methods=["POST"])
            def login():
                username = request.json.get("username", None)
                password = request.json.get("password", None)
                if username != "test" or password != "test":
                    return jsonify({"msg": "Bad username or password"}), 401

                # You can use the additional_claims argument to either add
                # custom claims or override default claims in the JWT.
                additional_claims = {"aud": "some_audience", "foo": "bar"}
                access_token = create_access_token(username, additional_claims=additional_claims)
                return jsonify(access_token=access_token)

토큰값에서 정보 조회하기

  • get_jwt_identity() 를 사용하면 식별자로 넣어준 값들을 조회 할 수 있다

유효 토큰이 있을 때만 접근 허용하기


@app.route("/users/protected")
@jwt_required()
def protected():
    current_user_id = get_jwt_identity()
    return jsonify(logged_in_as=current_user_id), 200

if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)

참고. POST맨에서 토큰 값 보내기

@jwt_required(optional=True)

@jwt_required()에 optional 값을 True로 주면 유효 토큰이 있는지 없는지에 따라 분기처리를 할 수 있다

@jwt_required(optional=True)
def place(place_id):
    current_identity = get_jwt_identity()
    if not current_identity:
        return jsonify({'result':'fail'})

    places = to_place_detail_dto(
        list(db.places.find({'_id': ObjectId(place_id)})))
    return jsonify({'places': places})

토큰 만료시 개별 처리

토큰이 만료된 토큰으로 요청시 {"msg": "Token has expired"} 라는 메시지가 자동으로 전송되는데 우리는 서버사이드랜더링이었으므로 이를 제어해서 다른 처리를 해줘야 했다.

문제 토큰을 세션에 추가해줘야 서버사이드 랜더링

app = Flask(__name__)

# Configure application to store JWTs in cookies. Whenever you make
# a request to a protected endpoint, you will need to send in the
# access or refresh JWT via a cookie.
app.config['JWT_TOKEN_LOCATION'] = ['cookies']

# Set the cookie paths, so that you are only sending your access token
# cookie to the access endpoints, and only sending your refresh token
# to the refresh endpoint. Technically this is optional, but it is in
# your best interest to not send additional cookies in the request if
# they aren't needed.
app.config['JWT_ACCESS_COOKIE_PATH'] = '/api/'
app.config['JWT_REFRESH_COOKIE_PATH'] = '/token/refresh'

# Disable CSRF protection for this example. In almost every case,
# this is a bad idea. See examples/csrf_protection_with_cookies.py
# for how safely store JWTs in cookies
app.config['JWT_COOKIE_CSRF_PROTECT'] = False
  • 이 설정 부분을 꼭 추가해줘야 한다는 것
  • 이렇게 완성했다

logout

https://flask-jwt-extended.readthedocs.io/en/stable/refreshing_tokens/

  • 이를 보고 구현했다
@app.route('/signout', methods=['POST'])
def signout():
    response = make_response(redirect(url_for("places_all")))
    unset_jwt_cookies(response)
    return response

추가

profile
spring, java학습

0개의 댓글

관련 채용 정보