2012-02-01 11 views
8

Tôi đang làm việc trên một ứng dụng bình cần xác thực. Tôi đã kết nối đăng nhập bình nhưng nó không có vẻ rất duyên dáng.sử dụng bình-đăng nhập với postgresql

Đầu tiên bình-đăng nhập cần phải chắc chắn rằng người dùng tồn tại:

@login_manager.user_loader 
def load_user(id): 
    return User.query.get(id) 

Nhưng bạn cũng cần phải sử dụng 'login_user' để tạo ra các đối tượng người dùng

# Some code above 
    user = User.query.filter_by(email = form.email.data, password = form.password.data).first() 
    user.login_status = 1 
    db.session.commit() 
    login_user(objects.SignedInUser(user.id, user.email, user.login_status == LoginStatus.Active))  
# Some code below 

Trong đoạn mã trên 'tài 'là một mô hình cho postgres và SignedInUser chỉ là một đối tượng được sử dụng để đăng nhập bình.

Có ai có ví dụ về thông tin đăng nhập bình được sử dụng với postgres không?

Trả lời

35

Có vẻ như bạn có thể hiểu nhầm về các thao tác xử lý Flask-Login. Nó có để theo dõi mọi thứ về phiên của người dùng sau khi bạn cho biết xác thực thành công (bằng cách gọi login_user.) Gọi lại user_loader chỉ cho biết cách tải lại đối tượng cho người dùng đã được xác thực, chẳng hạn như khi ai đó kết nối lại một phiên "nhớ tôi". Các tài liệu không đặc biệt rõ ràng về điều đó.

Không cần phải giữ cờ trong cơ sở dữ liệu cho trạng thái đăng nhập của người dùng. Ngoài ra, mã bạn đưa vào sẽ tăng AttributeError nếu thông tin đăng nhập không đúng (user = None).

Đây là ví dụ từ ứng dụng Flask-SQLAlchemy. Nó sử dụng một nguồn xác thực bên ngoài và một trình bao bọc cho đối tượng SQLAlchemy User, nhưng quá trình này về cơ bản giống nhau.

user_loader callback:

@login_manager.user_loader 
def load_user(user_id): 
    user = User.query.get(user_id) 
    if user: 
     return DbUser(user) 
    else: 
     return None 

lớp người dùng (wrapper cho đối tượng SQLAlchemy):

# User class 
class DbUser(object): 
    """Wraps User object for Flask-Login""" 
    def __init__(self, user): 
     self._user = user 

    def get_id(self): 
     return unicode(self._user.id) 

    def is_active(self): 
     return self._user.enabled 

    def is_anonymous(self): 
     return False 

    def is_authenticated(self): 
     return True 

Đăng nhập handler:

@app.route('/login', methods=['GET', 'POST']) 
def login(): 
    error = None 
    next = request.args.get('next') 
    if request.method == 'POST': 
     username = request.form['username'] 
     password = request.form['password'] 


     if authenticate(app.config['AUTH_SERVER'], username, password): 
      user = User.query.filter_by(username=username).first() 
      if user: 
       if login_user(DbUser(user)): 
        # do stuff 
        flash("You have logged in") 

        return redirect(next or url_for('index', error=error)) 
     error = "Login failed" 
    return render_template('login.html', login=True, next=next, error=error) 

Lưu ý rằng đăng nhập thất bại nếu:

  • auth bên ngoài không
  • người dùng truy vấn trả về None (người dùng không tồn tại)
  • login_user lợi nhuận False (user.is_active() == False)

Thoát

@app.route('/logout') 
@login_required 
def logout(): 
    logout_user() 
    flash('You have logged out') 
    return(redirect(url_for('login'))) 
+1

bạn không cần một @login_required cho phương pháp logout –

+1

tôi đã thêm nó để đăng xuất –

+0

Loại công cụ nào thuộc "nếu login_user (DbUser (người dùng)): # do stuff"? – Mittenchops