アプリケーション認可

すべての良い一日。 この記事では、特にC ++ Qt 4での承認システムの設計における実際の経験について説明します。多くの経験豊富なプログラマーにとって、以下のすべては当たり前ですが、旅を始めたい初心者にとっては、この経験は役に立ちます。 最小限の単語、主にコードの切り抜き。



なぜ認証が必要なのですか? なんという質問でしょう、彼らは皆知っています。 つまり、承認は、ユーザーをシステムに入力することと、システムの機能にアクセスする権利を制限することの両方に役立ちます。 移植性のために、いわば別のモジュールで割り当てられています。これにより、異なるプロジェクトで同じコードを使用できます。



認証はどこから始まりますか? もちろん、ユーザーとパスワードの入力ウィンドウから! 表示方法は次のとおりです。







ここではすべてが標準的で明確です。 ログインとパスワードのフィールド、そしてもちろん、「記憶」チェックボックス。 青年期に一度は使用しませんでした。 しかし、このチェックボックスを入力すると、明らかにユーザーの作業が楽になりました。 「設定」ボタンの後ろには、データベースへの接続を設定するためのウィンドウがあります。



そして中身は何ですか?



main()関数は、ほとんどすべてがシンプルで明確です。



int main(int argc, char *argv[]) { QApplication a(argc, argv); //   QTextCodec::setCodecForLocale(QTextCodec::codecForName("cp1251")); QTextCodec::setCodecForTr(QTextCodec::codecForName("cp1251")); frmMain w; ProgSettings sett; DlgAuth dlg; dlg.setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog); //         //   "" dlg.setUserName(sett.LastUser()); dlg.setRemember(sett.IsRemember()); //    "" //    (   ), //      if (dlg.IsRemember() && DBConnector::CanConnectToDB()) { DBConnector::ConnectToDB(); dlg.setPassword(sett.SavePassword()); } //      ,     if ((DBConnector::CanConnectToDB() && sett.IsRemember() && coreUsers::Auth(sett.LastUser(),sett.SavePassword())) || dlg.exec() == QDialog::Accepted) { w.show(); //   -  sett.setLastUser(dlg.UserName()); sett.setSavePassword(dlg.Password()); sett.setIsReminder(dlg.IsRemember()); } else return 0; return a.exec(); }
      
      







CanConnectToDB()関数は、データベースに接続するためのパラメーターの正確さをチェックします(最初にプログラムが起動された場合、設定はまだないため、関数はfalseを返します)。



ProgSettingsクラスは、プログラム設定を操作するために使用され、それぞれに特別なものは何もありません。 停止しません。

また、おそらく最も重要な関数であるAuth()関数についても検討する必要があります。



 bool coreUsers::Auth(QString login, QString pwd) { QSqlQuery sql; bool Ok = false; sql.exec(QString("SELECT * FROM %1 WHERE %2 = '%3'") .arg(UserTable::tableName()) .arg(UserTable::loginField()) .arg(login)); if (sql.lastError().isValid()) { QMessageBox::information(QApplication::activeWindow(),tr(""), sql.lastError().text(),QMessageBox::Ok); return false; } if (sql.size() > 0) { sql.next(); if (QString::compare(Cryptor::Decode(sql.record().field(UserTable::pwdField()).value().toString()) ,pwd,Qt::CaseSensitive)!=0) { QMessageBox::information(QApplication::activeWindow(),tr(""),tr(" ! ") ,QMessageBox::Ok); } else { if (sql.record().field(UserTable::lockField()).value().toBool()) QMessageBox::information(QApplication::activeWindow(),tr(""), tr(" '%1' .").arg(login),QMessageBox::Ok); else { Ok = true; SetActiveUser(new SystemUser(sql.record().field(UserTable::idField()).value().toInt(), login,"", sql.record().field(UserTable::nameField()).value().toString())); } } } else QMessageBox::information(QApplication::activeWindow(),tr(""), tr("     !"),QMessageBox::Ok); return Ok; }
      
      







SystemUserクラスの静的インスタンスを作成するSetActiveUser()関数を除き、プログラム全体の機能へのアクセスを制限するためのさらなる作業に必要なコメントはありません。

UserTableクラスは、ユーザーテーブルのラッパークラスです。



 class UserTable { public: static QString tableName() { return "sy_user"; } static QString loginField() { return "us_login"; } static QString pwdField() { return "us_pwd"; } static QString idField() { return "us_id"; } static QString nameField() { return "us_name"; } static QString lockField() { return "us_lock"; } static QString onlineField() { return "us_online"; } static QString onlineTimeField(){ return "us_online_time"; } static bool IsEmpty(); //          static void CreateFirstUser(); };
      
      







パスワードを保存することは注目に値します。パスワードはレジストリに書き込まれ、データベーステーブルは暗号化されます。 ユーザーテーブルのパスワードとデータベースサーバーに接続するためのパスワードは、同じアルゴリズムとキーで暗号化されます。 ところで、実際には、多くの深刻なプログラムが暗号化されていないパスワードをシステムレジストリに書き込むことがよくありますが、それは正常なことですか

パスワードの暗号化はアプリケーションレベルで行われるため、最初にシステムにアクセスしようとすると、システムの最初のユーザー(プログラムをまったく入力しないユーザー)が次の関数で作成されます。



 void UserTable::CreateFirstUser() { if (!QSqlDatabase::database().isOpen() && !UserTable::IsEmpty()) return; QSqlQuery sql; sql.exec(QString("INSERT INTO %1 (%2, %3) VALUES('admin', '%4');") .arg(tableName()) .arg(loginField()) .arg(pwdField()) .arg(Cryptor::Encode("admin"))); if (sql.lastError().isValid()) { qDebug() << sql.lastError().text(); } else { UserLimitTable::AddLimit(sql.lastInsertId().toInt(),100); } }
      
      







すぐに、ユーザー制限テーブルのラッパークラスが必要になります。



 class UserLimitTable { public: static QString TableName() { return "sy_user_limit"; } static QString limitIdField() { return "ul_limit"; } static QString userIdField() { return "ul_us_id"; } static void AddLimit(int userID, int limitID); };
      
      







そして最後に、SystemUserクラス:



 class SystemUser { public: SystemUser(int id, QString login, QString pwd, QString name); //     QList<int> Limits() {return limits;} int id() {return Id;} QString login() {return Login;} QString password() {return Password;} QString userName() {return UserName;} QDateTime startSessionTime() {return StartSessionTime;} void setId(int value) {Id = value;} void setLogin(QString value) { Login = value;} void setPassword(QString value) {Password = value;} void setUserName (QString value) {UserName = value;} void setStartSessionTime (QDateTime value) { StartSessionTime = value;} private: QList<int> limits; int Id; QString Login; QString Password; QString UserName; QDateTime StartSessionTime; };
      
      







ユーザー制限は、SystemUserコンストラクターのユーザー制限テーブルから入力される通常のQListリストに保存されます。 現在のユーザーの機能をさらに制限します。



その結果、ほとんどすべてのアプリケーションの複雑さに適した認証システムが得られます。 テーブルラッパーのクラスに基づいて、すべてのデータベースクエリが構築され、別のプロジェクトに転送されると、テーブルフィールド名は独自のクエリに置き換えられます。 とても便利です。



最後まで読んでくれてありがとう。



All Articles