簡體   English   中英

如何使用fmdb登錄頁面?

[英]How to use fmdb for a login page?

我有一個登錄頁面,其中包含2個用於用戶名和密碼的文本字段以及一些按鈕。 我想知道如何使用fmdb檢查數據庫中是否存在用戶名/密碼組合? 我還為用戶注冊頁面使用了另一個viewcontroller,其中有4個用於用戶名,密碼,電子郵件,聯系電話的文本字段,以及一個將輸入的文本輸入數據庫的按鈕。 如何將4個字段中輸入的文本保存到數據庫中? 提前致謝。 這是我的代碼:我已成功將數據輸入到registerViewController的數據庫中,但是如果用戶忘記了密碼和/或用戶名,我想將代碼輸入到“ btnforgot”(忘記密碼)操作中。 我也已經在loginViewController中取得了一些成功,就檢查用戶名和密碼是否與數據庫中的用戶名和密碼相匹配而言,但是我想我在兩者之間缺少了一些東西。

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捆綁包:(NSBundle *)nibBundleOrNil {self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if(self){//自定義初始化}返回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];


}

如果要檢查數據庫中是否包含用戶名/密碼組合,可以:

#import "FMDatabaseAdditions"

然后您可以查看userid /密碼組合是否符合成功登錄的要求,如下所示:

BOOL success = NO;

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

if (count > 0)
    success = YES;

話雖如此,我從微不足道的到批評的都有以下幾點觀察:

  1. 現在,您始終在報告“已添加聯系人”。 您應該真正確定插入是否成功。 您可以通過檢查executeUpdate方法返回的值來完成此操作(如果成功,則返回YES ,如果INSERT失敗,則返回NO )。

  2. 使用PRIMARY KEY AUTOINCREMENT鍵時,不應使用DEFAULT 0 首先,我認為不會完成任何事情(無論從1開始)。 其次,即使這樣做,也很難使用零,因為FMDB的lastInsertRowId (調用SQLite sqlite3_last_insert_rowid對數字鍵使用零值來指定錯誤。 因此,永遠不要使用零。

  3. 更重要的是,您永遠不要在未加密的設備上存儲密碼。 (即使您不關心應用程序的安全性,也有太多的用戶重復使用密碼,因此,您要確保您不會成為破壞其密碼的一種可能方式。)

    至少,您希望在將密碼存儲在數據庫中時對其進行加密,然后在登錄時對用戶提供的密碼進行加密,並比較這兩個加密的密碼。 如果要查看某些可用的加密服務,請參閱《 加密服務指南》

  4. 話雖這么說,您甚至可能不想自己編寫任何密碼加密代碼(正確執行此操作並不容易)。

    使用iOS鑰匙串可能更好。 蘋果公司在該主題上的入門書籍是WWDC 2013視頻《使用鑰匙串保護秘密》

    例如,要保存與用戶標識關聯的密碼,電子郵件地址和號碼,您可以執行以下操作:

     // 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); 

    然后,當您要登錄時,可以執行以下操作:

     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]; } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM