如何使用fmdb登录页面? [英] How to use fmdb for a login page?

查看:103
本文介绍了如何使用fmdb登录页面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个登录页面,其中包含2个用户名和文本字段密码和几个按钮。我想知道如何使用fmdb来检查我的数据库中是否存在用户名/密码组合?我还有另一个用于用户注册页面的viewcontroller,有4个用于用户名,密码,电子邮件,联系人号码的文本字段以及一个用于将输入的文本输入数据库的按钮。如何将4个字段中输入的文本保存到数据库中?提前致谢。这是我的代码:
我成功地将数据输入数据库,在registerViewController中,但是如果用户忘记密码和/或用户名,我想在btnforgot(忘记密码)操作中输入代码。我在loginViewController中也有所成功,只要检查用户名和&密码在数据库中匹配与否相同,但我想我之间缺少某些东西(一些代码)。

I have a login page that has 2 textfields for username & password and a few buttons. I want to know that how I can use fmdb for checking if the username/password combination exists in my database? I also have another viewcontroller used for the user registeration page, having 4 textfields for username, password, email, contact number and a button to input the entered text into the database. How can I save the entered text in 4 fields to the database? Thanks in advance. Here is my code: I succeeded in entering the data into the database,in the registerViewController but I want to enter code into the "btnforgot"(forgot Password) action if the user forgets the password and/or username. I've been successful somewhat in the loginViewController too,as far as checking if the username & password match the same in the database or not,but i guess i am missing something(some code) in between.

LOGINVIEW


#import "loginViewController.h"
#import "carTypeViewController.h"
#import "registerViewController.h"
#import "FMDatabase.h"
#import "AppDelegate.h"
#import "FMDatabaseAdditions.h"
@interface loginViewController ()

@end
@implementation loginViewController
@synthesize lblPass,lblUserName,txtPass,txtUser;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self){
//自定义初始化
}
返回self;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; }

- (void)viewDidLoad

{
self.title = @"Enter Credentials";
username = [[NSMutableArray alloc]init];
password = [[NSMutableArray alloc]init];

[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)btnLogin:(id)sender
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:@"contacts.db"];
FMDatabase *database = [FMDatabase databaseWithPath:path];

[database open];

BOOL success = NO;

    NSInteger count = [database intForQuery:@"select count(*) from RegMembers where USERNAME = ? and PASSWORD = ?", username, password];

if ([txtUser.text length] == 0 || [txtPass.text length]== 0){
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:@"Kindly enter details in all fields" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
    [alert show];
}

else if (count > 0)
{
        success = YES;

        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Welcome" message:@"Login successful" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
        [alert show];

        carTypeViewController *car = [[carTypeViewController alloc]initWithNibName:@"carTypeViewController" bundle:nil];
        [self.navigationController pushViewController:car animated:YES];

}
    else
    {
        UIAlertView *alert1 = [[UIAlertView alloc]initWithTitle:@"Kindly enter the correct credentials" message:@"Entered username or password is incorrect" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
        [alert1 show];

        txtUser.text=@"";
        txtPass.text=@"";
    }
[database close];
}
-(IBAction)removeKeyboard
{
[self.txtUser resignFirstResponder];
[self.txtPass resignFirstResponder];
}

- (IBAction)btnSignUp:(id)sender {
registerViewController *reg = [[registerViewController alloc]initWithNibName:@"registerViewController" bundle:nil];
[self.navigationController pushViewController:reg animated:YES];
}


- (IBAction)btnExit:(id)sender {
exit(1);

}

- (IBAction)btnForgotPass:(id)sender {
}

@end






REGISTERVIEW

- (void)viewDidLoad
{
self.title = @"Create Account";
[super viewDidLoad];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,      NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:@"contacts.db"];
FMDatabase *database = [FMDatabase databaseWithPath:path];

[database open];

[database executeUpdate:@"create table if not exists RegMembers (ID INTEGER NOT NULL     PRIMARY KEY AUTOINCREMENT DEFAULT 0, USERNAME TEXT UNIQUE NOT NULL , PASSWORD TEXT NOT NULL     , EMAIL TEXT NOT NULL , NUMBER TEXT  NOT NULL)"];

[database close];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

-(IBAction)removeKeyboard
{
[self.txtUname resignFirstResponder];
[self.txtPass resignFirstResponder];
[self.txtEmail resignFirstResponder];
[self.txtNumber resignFirstResponder];

}
- (IBAction)btnUAcount:(id)sender
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,     NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:@"contacts.db"];
FMDatabase *database = [FMDatabase databaseWithPath:path];

if ([txtUname.text length] == 0 ||
    [txtPass.text length]== 0   ||
    [txtEmail.text length]== 0  ||
    [txtNumber.text length]== 0)
{
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:@"Kindly     enter details in all fields" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
    [alert show];

}
else

{
    if ([database open])
    {

        [database executeUpdate:@"insert into RegMembers(username, password, email,     number) values(?,?,?,?)",
        [NSString stringWithFormat: @"%@",txtUname.text],[NSString     stringWithFormat:@"%@",txtPass.text],[NSString stringWithFormat:@"%@",txtEmail.text],    [NSString stringWithFormat:@"%@",txtNumber.text],nil];
        if (1)
        {
            NSLog(@"contact added");
            self.txtUname.text = @"";
            self.txtPass.text = @"";
            self.txtEmail.text = @"";
            self.txtNumber.text = @"";
        }
        else
        {
            NSLog(@"failed to add contact");
        }

    }
    [database close];
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Registeration succesful"     message:@"Thanks for choosing edmunds" delegate:nil cancelButtonTitle:@"OK"     otherButtonTitles: nil];
    [alert show];
    [self.navigationController popViewControllerAnimated:YES];


}


推荐答案

如果要检查用户ID /密码组合是否在数据库中,您可以:

If you want to check to see if the userid/password combination is in your database, you can:

#import "FMDatabaseAdditions"

然后您可以看到用户ID /密码组合是否有资格成功登录:

and then you can see if the userid/password combination qualifies as a successful login like so:

BOOL success = NO;

NSInteger count = [database intForQuery:@"select count(*) from RegMembers where USERNAME = ? and PASSWORD = ?", username, password];

if (count > 0)
    success = YES;

话虽如此,我还有一些观察,从琐碎到关键:

Having said that, I have a couple of observations ranging from the trivial to the critical:


  1. 现在您总是报告已添加联系人。您应该确定插入是否成功。你可以通过检查 executeUpdate 方法返回的值来做到这一点(如果成功则返回 YES 如果 INSERT 失败)。

  1. Right now you're always reporting "contact added". You should really determine whether the insert succeeded or not. You can do this by checking the value returned by the executeUpdate method (returns YES if successful, NO if the INSERT failed).

使用<时code> PRIMARY KEY AUTOINCREMENT 键,你不应该使用 DEFAULT 0 。首先,我不认为这会完成任何事情(无论如何,它将从 1 开始)。第二,即使它确实如此,使用零也是非常糟糕的,因为FMDB的 lastInsertRowId ,它调用SQLite sqlite3_last_insert_rowid ,使用零值表示数字键来指定错误。所以,永远不要使用零。

When using a PRIMARY KEY AUTOINCREMENT key, you should not use DEFAULT 0. First, I don't think that accomplishes anything (it will start at 1, regardless). Second, even if it did, it would be very bad to use zero because FMDB's lastInsertRowId, which calls SQLite sqlite3_last_insert_rowid, uses zero value for the numeric key to designate an error. So, never use zero.

更重要的是,你应该永远在未加密的设备上存储密码。 (即使您不关心应用程序的安全性,也有太多用户重新使用密码,因此您需要确保不会成为密码泄密的可能方式。)

Far more critical, you should never store passwords on the device unencrypted. (Even if you don't care about the security of your app, too many users re-use passwords, so you want to make sure that you don't become a possible way for their password to be compromised.)

至少,您希望在将密码存储在数据库中时加密密码,然后在登录时加密用户提供的密码,并比较两个加密密码。如果您想查看一些可用的加密服务,请参阅加密服务指南

At the very least, you'd want to encrypt the password when you store it in the database, and then, when logging in, encrypt the password that the user provided, and compare the two encrypted passwords. If you want to see some of the cryptographic services available, see the Cryptographic Services Guide.

话虽如此,您甚至可能不想自己编写任何密码加密代码(要做到这一点并不是完全无关紧要) 。

Having said that, you might not even want to write any password encryption code yourself (to do this properly is not entirely trivial).

使用iOS Keychain可能更好。 Apple关于该主题的入门读物是WWDC 2013视频使用钥匙串保护秘密

Using the iOS Keychain is probably better. Apple's primer on the topic is the WWDC 2013 video Protecting Secrets with the Keychain.

例如,要保存与用户ID相关联的密码,电子邮件地址和号码,您可以执行以下操作:

For example, to save the password, email address, and number associated with a userid, you could do something like:

// see if the userid already exists

NSDictionary* query = @{(__bridge id)kSecClass       : (__bridge id)kSecClassGenericPassword,
                        (__bridge id)kSecAttrService : @"com.domain.app",
                        (__bridge id)kSecAttrAccount : self.useridTextField.text,
                        (__bridge id)kSecMatchLimit  : (__bridge id)kSecMatchLimitOne,
                        (__bridge id)kSecReturnData  : @NO};

OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL);

if (status == errSecSuccess)
{
    [[[UIAlertView alloc] initWithTitle:nil message:@"That userid is already registered" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
    return;
}

// create payload of secret data

NSDictionary *secret = @{@"password" : self.passwordTextField.text ?: [NSNull null],
                         @"email"    : self.emailTextField.text    ?: [NSNull null],
                         @"number"   : self.numberTextField.text   ?: [NSNull null]};

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:secret];

// create keychain query

query = @{(__bridge id)kSecClass       : (__bridge id)kSecClassGenericPassword,
          (__bridge id)kSecAttrService : @"com.domain.app",
          (__bridge id)kSecAttrAccount : self.useridTextField.text,
          (__bridge id)kSecValueData   : data};

// add data associated with the userid in the keychain

status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
NSAssert(status == errSecSuccess, @"%s: SecItemAdd error: %lu", __FUNCTION__, (unsigned long)status);

然后,当您想要登录时,您可以执行以下操作:

Then, when you want to log in, you can do something like:

BOOL success = NO;

NSDictionary* query = @{(__bridge id)kSecClass       : (__bridge id)kSecClassGenericPassword,
                        (__bridge id)kSecAttrService : @"com.domain.app",
                        (__bridge id)kSecAttrAccount : self.useridTextField.text,
                        (__bridge id)kSecMatchLimit  : (__bridge id)kSecMatchLimitOne,
                        (__bridge id)kSecReturnData  : @YES};

CFTypeRef typeRef;

OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &typeRef);

// if we found keychain entry for that userid, check the password

if (status == noErr)
{
    NSDictionary *dictionary = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)typeRef];
    NSAssert(dictionary, @"%s: unarchiveObjectWithData failed: %@", __FUNCTION__, (__bridge NSData *)typeRef);
    NSString *password = dictionary[@"password"];
    if ([self.passwordTextField.text isEqualToString:password])
        success = YES;

    CFRelease(typeRef);
}

// if we didn't succeed for any reason, tell the user

if (!success)
{
    [[[UIAlertView alloc] initWithTitle:nil message:@"Login failed" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil] show];
}


这篇关于如何使用fmdb登录页面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆