求助:如何实现iOS(Swift)对接Django数据库的登录功能
Hey there! Since you already have the web Facebook-only login working with Django, let’s walk through how to add standard username/password login for your iOS app in Swift. We’ll split this into backend tweaks and iOS implementation steps to make it straightforward.
Step 1: Prepare Django Backend for Login API
First, you need a dedicated API endpoint that your iOS app can call to authenticate users. If you’re not already using it, Django REST Framework (DRF) is perfect for this. Here’s how to set it up:
Install required packages if you haven’t:
pip install djangorestframework pip install django-cors-headers # To handle cross-origin requests from iOSUpdate your
settings.pyto enable DRF and CORS:INSTALLED_APPS = [ # ... your existing apps 'rest_framework', 'rest_framework.authtoken', # For token-based authentication 'corsheaders', ] MIDDLEWARE = [ # ... your existing middleware 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ] # Allow your iOS app to access the backend (adjust origins for production) CORS_ALLOWED_ORIGINS = [ "http://localhost:8000", # Local development "https://your-production-domain.com", ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.TokenAuthentication', ], }Create a custom login view in your app’s
views.py:from rest_framework.views import APIView from rest_framework.response import Response from django.contrib.auth import authenticate from rest_framework.authtoken.models import Token class CustomLoginView(APIView): def post(self, request): username = request.data.get('username') password = request.data.get('password') user = authenticate(username=username, password=password) if user: # Get or create an auth token for the user token, created = Token.objects.get_or_create(user=user) return Response({ 'token': token.key, 'user_id': user.id, 'username': user.username }) else: return Response({'error': 'Invalid username or password'}, status=400)Add the login endpoint to your
urls.py:from django.urls import path from .views import CustomLoginView urlpatterns = [ # ... your existing URLs path('api/login/', CustomLoginView.as_view(), name='api-login'), ]
Step 2: Implement Login in Swift iOS App
Now let’s build the iOS side using native URLSession (you can swap this for Alamofire if you prefer, but native works great for basic flows):
First, set up your login UI (you probably have this already, but just in case):
- Add two
UITextFields for username and password - Add a
UIButtonfor login - Connect these to your view controller with IBOutlets/IBActions
- Add two
Write the login request logic in your view controller:
import UIKit class LoginViewController: UIViewController { @IBOutlet weak var usernameTextField: UITextField! @IBOutlet weak var passwordTextField: UITextField! @IBAction func loginButtonTapped(_ sender: UIButton) { guard let username = usernameTextField.text, !username.isEmpty, let password = passwordTextField.text, !password.isEmpty else { showAlert(title: "Oops", message: "Please fill in both username and password") return } performLogin(username: username, password: password) } private func performLogin(username: String, password: String) { guard let apiUrl = URL(string: "http://your-django-domain.com/api/login/") else { showAlert(title: "Error", message: "Invalid API address") return } var request = URLRequest(url: apiUrl) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") let loginPayload = ["username": username, "password": password] do { request.httpBody = try JSONSerialization.data(withJSONObject: loginPayload) } catch { showAlert(title: "Error", message: "Failed to prepare login data") return } let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in DispatchQueue.main.async { if let error = error { self?.showAlert(title: "Network Issue", message: error.localizedDescription) return } guard let responseData = data else { self?.showAlert(title: "Error", message: "No response from server") return } do { if let responseJson = try JSONSerialization.jsonObject(with: responseData, options: []) as? [String: Any] { if let authToken = responseJson["token"] as? String { // Save token to UserDefaults for future authenticated requests UserDefaults.standard.set(authToken, forKey: "userAuthToken") // Navigate to your main app screen self?.navigateToMainApp() } else if let errorMessage = responseJson["error"] as? String { self?.showAlert(title: "Login Failed", message: errorMessage) } } } catch { self?.showAlert(title: "Error", message: "Failed to parse server response") } } } task.resume() } private func showAlert(title: String, message: String) { let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default)) present(alert, animated: true) } private func navigateToMainApp() { // Replace with your actual main screen navigation logic if let mainVC = storyboard?.instantiateViewController(withIdentifier: "MainTabBarController") { navigationController?.setViewControllers([mainVC], animated: true) } } }Use the auth token for future API requests
Once the user logs in, include the saved token in all authenticated requests:func fetchUserProfile() { guard let token = UserDefaults.standard.string(forKey: "userAuthToken"), let profileUrl = URL(string: "http://your-django-domain.com/api/user/profile/") else { return } var request = URLRequest(url: profileUrl) request.setValue("Token \(token)", forHTTPHeaderField: "Authorization") let task = URLSession.shared.dataTask(with: request) { data, response, error in // Handle profile data parsing here } task.resume() }
Step 3: Integrate with Your Existing Facebook Login
You can unify both login flows easily:
- After Facebook login succeeds on iOS, send the Facebook credentials to your Django backend (you likely have this flow set up for web)
- Have your Django backend return the same auth token as the standard login flow
- Save the token to
UserDefaultsjust like we did above, so all subsequent API requests use the same token regardless of login method
Quick Security & Best Practice Notes
- Use HTTPS in production to keep user credentials and tokens secure
- For better token management, consider using JWT tokens instead of DRF’s default token (use the
djangorestframework-simplejwtpackage) - Add logic to handle token expiration (refresh tokens or prompt users to log in again)
内容的提问来源于stack exchange,提问作者user9718948

