django swift login system

2019-04-16 08:03发布

问题:

I have a django web app created already, with a simple user table (username/password). I also have an iOS app (swift) set up, and was wondering what would be the best way to go about coding the login system?

From what I have gathered from research - I will have to make REST calls to an API created from the existing django app. Would it be better to use TastyPie or Django Rest Framework for this?

Are there specific things I have to keep in mind when doing the API for the django app? Also, what would be the url that i use for the rest calls, would it be the existing server that the django web app is on?

回答1:

My qualifications for this answer come from 3 months of work on an identical system to the one you described. Your question holds many parts, so I will begin with the server.

From what I have gathered from research - I will have to make REST calls to an API created from the existing django app.

Correct, your clients (app, web, or otherwise) should communicate with your server through an API.

I have a django web app created already, with a simple user table (username/password).

Hopefully your "simple user table" uses the default Django user model, as 3rd party security frameworks are going to make your life much simpler when protecting an open API. Although it depends on your security needs, I recommend the Django OAuth Toolkit for its OAuth2 support, password reset workflow, and prebuilt URL endpoints for common authentication interactions. Even better, this library natively supports the Django Rest Framework.

Would it be better to use TastyPie or Django Rest Framework for this?

I do not have experience with TastyPie, however I can vouch for DRF. The generic views matched our major API design points well, and DRF's similarities to the Django Form API means our custom dashboard has a wonderful symmetry to the API. I recommend you first map out the major components of your API, then research both frameworks to learn which will fit your project best.

(Bonus Tip: If this is your first time designing a REST API, flip through a copy of Build APIs You Won't Hate)

Also, what would be the url that i use for the rest calls, would it be the existing server that the django web app is on?

Common practice is to host your API URLs on a subdomain, followed by a version path, such as api.example.com/v1/. The subdomain separates your URLs from core web pages and denotes these endpoints are specifically for your API. The version path is a good practice to support legacy APIs as you upgrade.

Are there specific things I have to keep in mind when doing the API for the django app?

Security is a big one. Depending on your API, there could be some sensitive parts of your application exposed to the public. Write tests to ensure you are not poking new holes in your security, and leave OAuth to the pros. Other than that, make sure your server is ready to handle your traffic, and spend plenty of time perfecting your model.

I also have an iOS app (swift) set up, and was wondering what would be the best way to go about coding the login system?

When coding client-side, always use best practices to retrieve and store credentials. Communicate with your server over SSL, store only what you need, and destroy the expected data when a user logs out. Remember, if your app stores usernames and passwords, it stores sensitive data (because people have a funny tendency to reuse passwords for important things). Finally, clearly communicate the login process to your users with helpful error messages and loading animations. As you can see by now, the login process is fairly complex, but if executed well it will feel effortless.



回答2:

  1. Login Form

    class ViewController: UIViewController, UITextViewDelegate, UITextFieldDelegate{
    
    
    @IBOutlet var txtemail: UITextField!
    @IBOutlet var txtpass1: UITextField!
    @IBOutlet var lbl1: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    
        txtemail.becomeFirstResponder()
    
    
    }
    @IBAction func btnlogin(_ sender: UIButton) {
    
    
        let useremail = txtemail.text
        let userpass = txtpass1.text
    
        if ((useremail!.isEmpty) || (userpass!.isEmpty))
    
        {
    
            Displayalert(usermessage: "All Fields Are Required...")
    
        }
    
        // MARK:- Display Id
    
        let useremailstore = UserDefaults.standard.string(forKey: "useremail")
    
        let userpasswordstore = UserDefaults.standard.string(forKey: "userpass")
    
        // MARK:- Login New Page
    
        if useremail != useremailstore
        {
            Displayalert(usermessage: "Enter Valid Email")
    
        }
    
        else if userpass != userpasswordstore
    
        {
    
            Displayalert(usermessage: "Enter Valid Password..")
        }
    
        else
        {
    
            let wel = storyboard?.instantiateViewController(withIdentifier: "welcomeViewController")as! welcomeViewController
    
            self.navigationController?.pushViewController(wel, animated: true)
    
        }
    
    
        if useremailstore == useremail
        {
            if userpasswordstore == userpass
            {
    
                UserDefaults.standard.set(true, forKey: "userlogin")
                UserDefaults.standard.synchronize()
    
                self.dismiss(animated: true, completion: nil)
    
            }
    
        }
    
    }
    
    
    
    @IBAction func btnforgotpass(_ sender: UIButton) {
    
        let pass = storyboard?.instantiateViewController(withIdentifier: "NewPassViewController")as! NewPassViewController
    
    
        self.navigationController?.pushViewController(pass, animated: true)
    
    
    
    }
    
    
    @IBAction func btnnewacc(_ sender: UIButton) {
    
        let login = storyboard?.instantiateViewController(withIdentifier: "RegisterViewController")as! RegisterViewController
    
    
        self.navigationController?.pushViewController(login, animated: true)
    
    }
    
    // MARK:- Alert function
    
    func Displayalert(usermessage:String)
    
    {
    
        let Myalert = UIAlertController(title: "Alert", message: usermessage, preferredStyle: UIAlertControllerStyle.alert)
    
        let Action = UIAlertAction(title: "ok", style: UIAlertActionStyle.default, handler: nil)
    
        Myalert.addAction(Action)
    
        self.present(Myalert, animated: true, completion: nil)
    }
    
    // MARK:- Password set
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
        if textField == txtpass1
    
        {
            let text = txtpass1.text
            let newLength = (text?.characters.count)! + string.characters.count - range.length
            return newLength <= 8 // Bool
        }
    
        return true
    
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    
        txtemail.resignFirstResponder()
        txtpass1.resignFirstResponder()
        return false
    }
    
    override func viewWillAppear(_ animated: Bool) {
    
        txtemail.text = ""
        txtpass1.text = ""
    
    
    }
    
  2. Register Form

class RegisterViewController: UIViewController, UITextFieldDelegate, UITextViewDelegate {

@IBOutlet var txtmail: UITextField!
@IBOutlet var txtpass: UITextField!
@IBOutlet var txtrepass: UITextField!


var defaults = UserDefaults.standard

var dict : NSMutableDictionary = ["":""]


override func viewDidLoad() {
    super.viewDidLoad()

    txtmail.becomeFirstResponder()
    return

    // Do any additional setup after loading the view.
}

// MARK:- Register

@IBAction func btnregister(_ sender: UIButton) {

    let useremail = txtmail.text
    let userpass = txtpass.text
    let userrepass = txtrepass.text



    if((useremail!.isEmpty) || (userpass!.isEmpty) || (userrepass!.isEmpty))

    {
        Displayalert(usermessage: "All Fields Are Required....")

    }

    if userpass != userrepass

    {

        Displayalert(usermessage: "Your Re-Password is Not valid....")
        txtrepass.text = ""

    }



    let validEmail = isValidEmail(stringValue: txtmail.text!)

    if validEmail
    {

        print("Email is Valid")

    }
    else
    {
        Displayalert(usermessage: "Email Is Not Valid...")

    }

    //MARK:- Store Data

    UserDefaults.standard.set(useremail, forKey: "useremail")
    UserDefaults.standard.set(userpass, forKey: "userpass")
    UserDefaults.standard.synchronize()

    //MARK:-  Conformation message

    let Myalert = UIAlertController(title: "Alert", message: "Registation is Successful.Thank you...", preferredStyle: UIAlertControllerStyle.alert)

    let Action = UIAlertAction(title: "ok", style: UIAlertActionStyle.default) { action in self.performSegue(withIdentifier: "firstview", sender: self)}

        Myalert.addAction(Action)

        self.present(Myalert, animated: true, completion: nil)
    }

//MARK:-  Alert Call

func Displayalert(usermessage:String)
{

    let Myalert = UIAlertController(title: "Alert", message: usermessage, preferredStyle: UIAlertControllerStyle.alert)

    let Action = UIAlertAction(title: "ok", style: UIAlertActionStyle.default, handler: nil)

    Myalert.addAction(Action)

    self.present(Myalert, animated: true, completion: nil)

}

//MARK:- Email Valid

func isValidEmail(stringValue: String) ->Bool {
    let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
    let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
    return emailTest.evaluate(with: stringValue)
}

//MARK:- Same & re-Password

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {


    if textField == txtpass

    {
    let text = txtpass.text
    let newLength = (text?.characters.count)! + string.characters.count - range.length
    return newLength <= 8 // Bool
    }

    if textField == txtrepass
    {

        let text = txtrepass.text
        let newLength = (text?.characters.count)! + string.characters.count - range.length
        return newLength <= 8 // Bool

    }

    return true
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {

    txtmail.resignFirstResponder()
    txtpass.resignFirstResponder()
    txtrepass.resignFirstResponder()
    return false

}