[英]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;
話雖如此,我從微不足道的到批評的都有以下幾點觀察:
現在,您始終在報告“已添加聯系人”。 您應該真正確定插入是否成功。 您可以通過檢查executeUpdate
方法返回的值來完成此操作(如果成功,則返回YES
,如果INSERT
失敗,則返回NO
)。
使用PRIMARY KEY AUTOINCREMENT
鍵時,不應使用DEFAULT 0
。 首先,我認為不會完成任何事情(無論從1
開始)。 其次,即使這樣做,也很難使用零,因為FMDB的lastInsertRowId
(調用SQLite sqlite3_last_insert_rowid
對數字鍵使用零值來指定錯誤。 因此,永遠不要使用零。
更重要的是,您永遠不要在未加密的設備上存儲密碼。 (即使您不關心應用程序的安全性,也有太多的用戶重復使用密碼,因此,您要確保您不會成為破壞其密碼的一種可能方式。)
至少,您希望在將密碼存儲在數據庫中時對其進行加密,然后在登錄時對用戶提供的密碼進行加密,並比較這兩個加密的密碼。 如果要查看某些可用的加密服務,請參閱《 加密服務指南》 。
話雖這么說,您甚至可能不想自己編寫任何密碼加密代碼(正確執行此操作並不容易)。
使用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.